我有一个试图将文本读入元素列表的XmlReader。我在阅读文本时遇到了麻烦:“a [z]”。如果我尝试使用文本“a [z]”(相同但有两个尾随空格),它可以正常工作。以下是一个例子:
TextReader tr = new StringReader("a [ z ]");
XmlReaderSettings settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
ProhibitDtd = false,
ValidationType = ValidationType.None,
XmlResolver = null,
CheckCharacters = false,
IgnoreProcessingInstructions = true,
};
XmlReader reader = XmlReader.Create(tr, settings);
reader.Read();
StringBuilder sb = new StringBuilder();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.Whitespace)
{
sb.Append(reader.Value);
reader.Read();
}
}
// sb.ToString() should be "a [ z ]"
运行时失败并显示以下消息:“System.Xml.XmlException:发生了意外的文件结束。第1行,第7位。”和堆栈跟踪:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
at System.Xml.XmlTextReaderImpl.FinishPartialValue()
at System.Xml.XmlTextReaderImpl.get_Value()
at LocalisationFormats.Tests.Shared.InlineElements.InlineElementHelperTest.Test()
当您尝试调试它时,Reader的ReadState为“Error”,而Reader.Value为“a [z”,然后您打破阅读器并获得OutOfMemoryExecption。
有人有什么建议吗?
编辑:根据Gregoire的建议从代码段中移除额外的if。
答案 0 :(得分:2)
我认为问题在于,当您将非Xml格式的字符串加载到XmlReader对象中时。
“XmlReader提供对XML数据流的只进,只读访问.XmlReader类符合W3C可扩展标记语言(XML)1.0和XML推荐中的命名空间。” &安培; “XmlReader在XML解析错误上抛出XmlException。” - MSDN XmlReader类文章http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx
尝试通过更改:
来加载和读取实际的Xml数据 TextReader tr = new StringReader("a [ z ]");
为:
TextReader tr = new StringReader("<node>a [ z ]</node>");
或者,如果您需要在自己的节点中每个部分:
TextReader tr = new StringReader("<node>a</node><node> </node><node>[</node><node> </node><node>z</node><node> </node><node>]</node>");
我正在为后一个例子提供完整的资源,因为我认为这就是你的目标。
TextReader tr = new StringReader("<node>a</node><node> </node><node>[</node><node> </node><node>z</node><node> </node><node>]</node>");
XmlReaderSettings settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
ProhibitDtd = false,
ValidationType = ValidationType.None,
XmlResolver = null,
CheckCharacters = false,
IgnoreProcessingInstructions = true,
};
XmlReader reader = XmlReader.Create(tr, settings);
reader.Read();
StringBuilder sb = new StringBuilder();
while (!reader.EOF)
{
string s = reader.ReadElementString();
if (s != " ")
{
sb.Append(s);
}
}
这将允许您遍历节点,获取完整的字符串值,没有例外。
〜的md5sum〜
答案 1 :(得分:0)
我已经检查过这个问题已经在.Net 4中得到修复,但截至本文帖子仍然在.Net 3.5中被破解。
答案 2 :(得分:0)
很抱歉疏通了一个有三年之久的问题,但我遇到了同样的问题。对于未来的任何googlers:
看起来OP和微软的人提出了这个问题 - connect.microsoft.com/VisualStudio/feedback:
感谢您报告此问题。我们已经在.NET 4.0中解决了这个问题。我们不打算在以前版本的.NET中修复它。升级到.NET 4.0将解决此问题。
谢谢, Arun Chandrasekhar, 高级项目经理, XML团队
对于我们这些仍然坚持使用.Net&lt; 4.0(在我的情况下是2.0)我用这个可怕的黑客来解决这个问题:
const string openSquareBracketReplacement = "##OSB##";
const string closeSquareBracketReplacement = "##CSB##";
xml = xml
.Replace("[", openSquareBracketReplacement)
.Replace("]", closeSquareBracketReplacement);
// Build an XmlReader and use it.
return xml
.Replace(openSquareBracketReplacement, "[")
.Replace(closeSquareBracketReplacement, "]");
显然这会完全打破CDATA处理,但这对我来说是可以的。