【问题标题】:XML Reader on SQL Table returning invalid XMLSQL 表上的 XML 阅读器返回无效的 XML
【发布时间】:2010-10-15 01:08:03
【问题描述】:

我有一个 SQL 表,其中有一个 varchar(8) 列,其中偶尔包含二进制数据。 (0x01、0x02 等...)。 (不能更改列的格式或内容。)

当我进入 SQL Server 2005 Management Studio 并运行查询时:

select * 
 from mytable 
 where clientID = 431620
 for xml auto

我得到了有用的结果。注意 proc_counts 是如何编码的:

<mytable clientID="431620" recno="19014235" pdate="2008-03-04T00:00:00"
   proc_counts="&#x1;&#x1;&#x2;&#x1;" otherstuff="foobar" 
   date="2008-02-17T00:00:00"/>

完全有效的 XML,AFAIK。现在,当我实际编写 C# 代码来读取这一行时,我在 ReadOuterXml 期间抛出异常:

SqlCommand cmd = new SqlCommand("select * from testing xml auto", connection);
using (XmlReader xrd = cmd.ExecuteXmlReader())
{
    xrd.Read();
    while (xrd.ReadState != ReadState.EndOfFile)
    {
        string s = xrd.ReadOuterXml();
        records.Add(s);
    }
}

这会抛出:XmlException 未处理。 '',十六进制值 0x01 是无效字符。我想要上面的 XML,但没有足够的 Google-fu 来弄清楚为什么我没有得到它。有什么建议吗?


要使用此类数据创建表,此 Transact SQL 代码在 SSMS 中工作:

create table testing
(clientid int, proc_counts varchar(8));
insert into testing values (1, 'normal');
insert into testing values (2, char(65) + char(1) + char(65));
select * from testing for xml auto;

更新:事后分析和解决方法

Dommer 可能是对的,这是 XmlTextReader 中的 Normalization 属性给我带来了问题。问题是(从 cmets 中可以看出)我发现几乎不可能从 (SqlCommand).ExecuteXmlReader() 转到任何可以让我靠近 XmlTextReaderNormalization 属性的东西。微软关于这方面的文档通常是矛盾的,或者完全是错误的。

所以我选择了一个解决方法。如果我只是使用SqlDataReader 来吸收输出,一切都很好。 XML 看起来很完美,解析也很好。

StringBuilder sb = new StringBuilder();
using(SqlDataReader dr = cmd.ExecuteReader())
{
    while(rdr.Read())
        sb.Append((string)rdr[0]);
}

【问题讨论】:

    标签: c# sql sql-server xml xmlreader


    【解决方案1】:

    这与 XmlTextReader.Normalization 属性有关。当您显式创建 XmlTextReader 时,此属性设置为 false,因此会解码“无效”字符。当隐式创建 XmlTextReader 时,Normalization 设置为 true。

    此处讨论该属性:

    http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader.normalization.aspx

    如果您“手动”进行处理 - 即创建 XmlTextReader - 我认为您将避免该错误。

    更新:

    框架的更新版本中的更改意味着“XmlReaderSettings.CheckCharacters = false”可能是 ASP.NET 2.0+ 中的方式。可以将 XmlReaderSettings 对象传递给 XmlReader.Create。

    【讨论】:

    • 从 cmd.ExecuteXmlReader() 到 XmlTextReader 在msdn.microsoft.com/en-us/library/aa336091(VS.71).aspx 中被简要提及,但它是错误的——你不能这样转换: XmlTextReader xrd = (XmlTextReader)cmd.ExecuteXmlReader() .这是一个运行时异常。
    • 不,它似乎已经改变了......像往常一样 - :-(。我正在查看我的一个旧应用程序。这里有一个讨论:social.msdn.microsoft.com/Forums/en-US/xmlandnetfx/thread/…
    • 我可以转换成 XmlReader,但不能转换成 XmlTextReader。这是新的,因为有提到能够直接在较旧的 MS 文档中进行转换。 ExecuteXmlReader 返回类型 XmlTextReaderImpl 并且无法转换为我找到的 XmlTextReader。
    • 这看起来很有希望:XmlReaderSettings.CheckCharacters
    • 我确实尝试过,但没有成功——抛出了同样的错误。我有一个解决方法,我会照做。
    【解决方案2】:

    例外是告诉你真相。 SQL Server 显然允许显示无效的 XML。试试这个:

    select *  from mytable  where clientID = 431620 for xml auto, BINARY BASE64
    

    【讨论】:

    • 应该是 ", binary base64" 但这仍然不是。抛出相同的异常。
    • 这必须在 reader 方面,因为我确信 Management Studio 不会为我重写我的 SQL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2017-05-16
    • 2015-05-27
    • 1970-01-01
    相关资源
    最近更新 更多