Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 替换无效XML字符的字符引用_C#_.net_Xml - Fatal编程技术网

C# 替换无效XML字符的字符引用

C# 替换无效XML字符的字符引用,c#,.net,xml,C#,.net,Xml,我正在使用ADO.NET将一些数据作为XML从SQL Server投影。我的一些数据包含在XML中无效的字符,如CHAR7,即 SQL Server包含无效字符,例如数字引用: <row A="This is BEL: &#x7;" /> 有没有一种简单的方法可以使它也适用于编码的XML?我更愿意避免使用整个字符串,以避免引入无效字符替换以外的更改 编辑:转换需要在我的C代码中完成,而不是在SQL中,这样才能集中实现转换。您可以将特殊字符包装在代码中。这会通知解析器忽略标记

我正在使用ADO.NET将一些数据作为XML从SQL Server投影。我的一些数据包含在XML中无效的字符,如CHAR7,即

SQL Server包含无效字符,例如数字引用:

<row A="This is BEL: &#x7;" />
有没有一种简单的方法可以使它也适用于编码的XML?我更愿意避免使用整个字符串,以避免引入无效字符替换以外的更改


编辑:转换需要在我的C代码中完成,而不是在SQL中,这样才能集中实现转换。

您可以将特殊字符包装在代码中。这会通知解析器忽略标记中的文本。要使用您的示例:

SELECT 'This is BEL: <![CDATA[' + CHAR(7) + ']]>' AS A FOR XML RAW

这将至少允许解析XML,尽管需要对文档结构进行轻微更改。

我使用正则表达式进行了另一次尝试。这应该处理十进制和十六进制字符代码。此外,这只会影响数字编码字符

public string ReplaceXMLEncodedCharacters(string input)
{
    const string pattern = @"&#(x?)([A-Fa-f0-9]+);";
    MatchCollection matches = Regex.Matches(input, pattern);
    int offset = 0;
    foreach (Match match in matches)
    {
        int charCode = 0;
        if (string.IsNullOrEmpty(match.Groups[1].Value))
            charCode = int.Parse(match.Groups[2].Value);
        else
            charCode = int.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber);
        char character = (char)charCode;
        input = input.Remove(match.Index - offset, match.Length).Insert(match.Index - offset, character.ToString());
        offset += match.Length - 1;
    }
    return input;
}

作为参考,这是我的解决方案。我已经构建了它,但对它进行了修改,以更紧密地匹配HtmlDecode的内部实现。下面的代码忽略代理项对

// numeric character references
static readonly Regex ncrRegex = new Regex("&#x?[A-Fa-f0-9]+;");

static string ReplaceInvalidXmlCharacterReferences(string input)
{
    if (input.IndexOf("&#") == -1)   // optimization
        return input;

    return ncrRegex.Replace(input, match =>
    {
        string ncr = match.Value;            
        uint num;
        var frmt = NumberFormatInfo.InvariantInfo;

        bool isParsed =
            ncr[2] == 'x' ?   // the x must be lowercase in XML documents
            uint.TryParse(ncr.Substring(3, ncr.Length - 4), NumberStyles.AllowHexSpecifier, frmt, out num) :
            uint.TryParse(ncr.Substring(2, ncr.Length - 3), NumberStyles.Integer, frmt, out num);

        return isParsed && !XmlConvert.IsXmlChar((char)num) ? "�" : ncr;
    });
}

谢谢你的建议!不幸的是,我只能修改C代码,不能修改SQL。数据来自太多的地方,无法全部更新。没问题!我不确定改变SQL的结构是否可以接受,但完全可以理解这是不可以接受的。我希望你能找到一个适合你的解决方案!请参阅以下网页。XMLTextWriter将自动替换字符。您可以获得特殊字符的完整列表并创建字典。很简单。完整的列表可以在wiki中找到@jdweng:我的问题是关于转换&x7;到�. 您的链接仅讨论如何将\u0007转换为&x7@道格拉斯,你想用&x3C;做什么。如果你把它转换成一个伟大的观点。。。似乎像HtmlEncode和HtmlDecode这样的库调用在这里肯定是一种方法,而不是手工操作,除非您想处理许多特殊情况。@EZI:我只需要替换无效的字符引用&x3C;是编码形式的有效XML,因此可以不使用它。再次感谢!这是我想要的,在解码字符上加入XmlConvert.IsXmlChar。我会再等几天,以防有更简单的解决方案;如果没有,我会接受你的回答。
SELECT 'This is BEL: <![CDATA[' + CHAR(7) + ']]>' AS A FOR XML RAW
public string ReplaceXMLEncodedCharacters(string input)
{
    const string pattern = @"&#(x?)([A-Fa-f0-9]+);";
    MatchCollection matches = Regex.Matches(input, pattern);
    int offset = 0;
    foreach (Match match in matches)
    {
        int charCode = 0;
        if (string.IsNullOrEmpty(match.Groups[1].Value))
            charCode = int.Parse(match.Groups[2].Value);
        else
            charCode = int.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber);
        char character = (char)charCode;
        input = input.Remove(match.Index - offset, match.Length).Insert(match.Index - offset, character.ToString());
        offset += match.Length - 1;
    }
    return input;
}
// numeric character references
static readonly Regex ncrRegex = new Regex("&#x?[A-Fa-f0-9]+;");

static string ReplaceInvalidXmlCharacterReferences(string input)
{
    if (input.IndexOf("&#") == -1)   // optimization
        return input;

    return ncrRegex.Replace(input, match =>
    {
        string ncr = match.Value;            
        uint num;
        var frmt = NumberFormatInfo.InvariantInfo;

        bool isParsed =
            ncr[2] == 'x' ?   // the x must be lowercase in XML documents
            uint.TryParse(ncr.Substring(3, ncr.Length - 4), NumberStyles.AllowHexSpecifier, frmt, out num) :
            uint.TryParse(ncr.Substring(2, ncr.Length - 3), NumberStyles.Integer, frmt, out num);

        return isParsed && !XmlConvert.IsXmlChar((char)num) ? "�" : ncr;
    });
}