首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在构造使用数据的XmlReader或XPathDocument之前,如何从基于XML的数据源中删除无效的十六进制字符?

在构造使用数据的XmlReader或XPathDocument之前,如何从基于XML的数据源中删除无效的十六进制字符?
EN

Stack Overflow用户
提问于 2008-08-21 18:47:49
回答 14查看 100.6K关注 0票数 76

在XmlReader中使用基于XML的数据源之前,有没有什么简单/通用的方法来清理它,这样我就可以优雅地使用不符合对XML的十六进制字符限制的XML数据?

注意:

  • 解决方案需要处理使用除UTF-8之外的字符编码的XML数据源,例如通过在XML文档声明处指定字符编码。在去除无效的十六进制字符的同时不损坏源的字符编码一直是一个主要的症结所在。
  • 删除无效的十六进制字符应该只删除十六进制编码值,因为您经常可以在包含字符串的数据中找到href值,该字符串恰好与十六进制字符的字符串匹配。

背景:

我需要使用符合特定格式的基于XML的数据源(比如Atom或RSS提要),但又希望能够使用已经发布的数据源,这些数据源按照XML规范包含无效的十六进制字符。

在.NET中,如果您有一个表示XML数据源的流,然后尝试使用XmlReader和/或XPathDocument对其进行解析,则会由于XML数据中包含无效的十六进制字符而引发异常。我目前尝试解决这个问题的方法是将Stream解析为一个字符串,并使用正则表达式删除和/或替换无效的十六进制字符,但我正在寻找一种性能更好的解决方案。

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2008-08-21 18:50:59

It 可能不是完美的(强调,因为人们错过了这份免责声明),但我在这种情况下所做的事情如下所示。您可以调整以与流一起使用。

代码语言:javascript
复制
/// <summary>
/// Removes control characters and other non-UTF-8 characters
/// </summary>
/// <param name="inString">The string to process</param>
/// <returns>A string with no control characters or entities above 0x00FD</returns>
public static string RemoveTroublesomeCharacters(string inString)
{
    if (inString == null) return null;

    StringBuilder newString = new StringBuilder();
    char ch;

    for (int i = 0; i < inString.Length; i++)
    {

        ch = inString[i];
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        //if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r')
        //if using .NET version prior to 4, use above logic
        if (XmlConvert.IsXmlChar(ch)) //this method is new in .NET 4
        {
            newString.Append(ch);
        }
    }
    return newString.ToString();

}
票数 78
EN

Stack Overflow用户

发布于 2009-03-13 06:12:17

我喜欢尤金的白名单概念。我需要做与原始海报类似的事情,但我需要支持所有Unicode字符,而不仅仅是0x00FD。XML规范是:

字符= #x9 | #xA | #xD | #x20-#xD7FF | #xE000-#xFFFD | #x10000-#x10FFFF

在.NET中,Unicode字符的内部表示只有16位,所以我们不能显式地‘允许’0x10000-0x10FFFF。XML规范明确禁止出现以0xD800开头的代理代码点。但是,如果我们在白名单中允许这些代理代码点,那么只要从.NET字符串中的utf-16字符的代理对生成正确的utf-8编码,utf-8编码就可能最终生成有效的XML。我还没有探索过这一点,所以我选择了更安全的方法,不允许在我的白名单中使用代理。

虽然尤金的解决方案中的注释具有误导性,但问题是我们排除的字符在XML中是无效的……它们是完全有效的Unicode代码点。我们不会删除‘`non utf-8字符’。我们正在删除格式良好的XML文档中可能不会出现的utf-8字符。

代码语言:javascript
复制
public static string XmlCharacterWhitelist( string in_string ) {
    if( in_string == null ) return null;

    StringBuilder sbOutput = new StringBuilder();
    char ch;

    for( int i = 0; i < in_string.Length; i++ ) {
        ch = in_string[i];
        if( ( ch >= 0x0020 && ch <= 0xD7FF ) || 
            ( ch >= 0xE000 && ch <= 0xFFFD ) ||
            ch == 0x0009 ||
            ch == 0x000A || 
            ch == 0x000D ) {
            sbOutput.Append( ch );
        }
    }
    return sbOutput.ToString();
}
票数 60
EN

Stack Overflow用户

发布于 2013-02-17 01:15:33

作为删除无效XML字符的方法,我建议您使用XmlConvert.IsXmlChar方法。它是从Silverlight Framework4开始添加的,现在也出现在.NET中。下面是一个小示例:

代码语言:javascript
复制
void Main() {
    string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    content = RemoveInvalidXmlChars(content);
    Console.WriteLine(IsValidXmlString(content)); // True
}

static string RemoveInvalidXmlChars(string text) {
    char[] validXmlChars = text.Where(ch => XmlConvert.IsXmlChar(ch)).ToArray();
    return new string(validXmlChars);
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}
票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档