【发布时间】:2016-07-21 15:55:39
【问题描述】:
我使用 XmlWriter 编写了一个 Xml 文件。 这是代码:
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("element1");
writer.WriteAttributeString("attrs1", Attrs1);
writer.WriteAttributeString("attrs2", Attrs2);
if (!string.IsNullOrWhiteSpace("element2"))
{
writer.WriteStartElement("element2");
writer.WriteCData(Element2);
writer.WriteEndElement();
}
if (!string.IsNullOrWhiteSpace("element3"))
{
writer.WriteStartElement("element3");
writer.WriteCData(Element3);
writer.WriteEndElement();
}
Element4.WriteXml(writer);
Element5.WriteXml(writer);
writer.WriteEndElement();
}
如您所见,element4 调用了一个名为“WriteXml()”的方法。这是那个方法:
public void WriteXml(XmlWriter writer)
{
if (m_PropertyValueList.Count > 0)
{
writer.WriteStartElement("element4");
foreach (var p in m_PropertyValueList)
{
if (p.CurrentValue != null)
{
writer.WriteStartElement("property");
writer.WriteAttributeString("name", p.PropertyName);
writer.WriteAttributeString("value", p.CurrentValue.ToString());
writer.WriteEndElement();
}
}
writer.WriteEndElement();
}
}
请注意,它会检查 p.CurrentValue != null。如果它为空,则该元素应写为空元素。在这种情况下, p.CurrentValue 为空,所以我确实想要一个空元素。您将在下面的 Xml 输出中看到将此元素编写为 .对我来说,它看起来像是正确地写了一个空元素,如果我在这里错了,请纠正我。
Xml 文件输出如下所示:
<?xml version="1.0" encoding="UTF-8"?>
-<element>
-<element 1 attrs1="Some Info" attrs2="More Info">
-<element2>
+<![CDATA[]]>
</element2>
-<element3>
-<![CDATA[ ]]>
</element3>
<element4/>
</element1>
</element>
然后我创建了一个方法来重新读取 Xml 文件。这就是它中断的地方。它可以很好地读取元素、元素 1、元素 2 和元素 3。但是,当它到达 element4 时,我开始遇到问题。我将在下面解释。
这里是 XmlReader 方法:
public void ReadXml(XmlReader reader)
{
if (reader.IsStartElement("element1"))
{
//
// Get the values of all the <element1> attributes
//
Attrs1= reader.GetAttribute("attrs1");
Attrs2 = reader.GetAttribute("attrs2");
//
// Read past <element1>
//
reader.Read();
while (true)
{
if (reader.IsStartElement("element2"))
{
Description = reader.ReadElementContentAsString();
}
else if (reader.IsStartElement("element3"))
{
Source = reader.ReadElementContentAsString();
}
else if (reader.IsStartElement("element4")) && (!reader.IsEmptyElement))
{
Element4.ReadXml(reader);
}
else if ((reader.IsStartElement("element5")) && (!reader.IsEmptyElement))
{
Element5.ReadXml(reader);
}
else
{
reader.MoveToContent();
reader.ReadEndElement();
break;
}
}
}
else
{
throw new XmlException("Expected <element1> element was not present");
}
}
请注意,如果 element4 IsStartElement 并且它不是空元素,它将调用 Element4.ReadXml()。这是那个方法:
public void ReadXml(XmlReader reader)
{
if ((reader.IsStartElement("element4")) && (!reader.IsEmptyElement))
{
reader.Read();
while (reader.IsStartElement("property"))
{
string propertyName = reader.GetAttribute("name");
string propertyValue = reader.GetAttribute("value");
SetValue(propertyName, propertyValue);
reader.Read();
}
//
// Read </element4>
//
reader.MoveToContent();
reader.ReadEndElement();
}
}
但是由于 element4 是空的,所以这个方法永远不会被调用。因此它将继续执行 else{} 语句并在到达 reader.ReadEndElement(); 时中断。我得到的错误信息是:
"Message: TestMethod myTestMethodName threw exception: System.Xml.XmlException 'Element' is an invalid XmlNodeType. Line 8, position 6."
所以我的问题是:
- 这是因为元素是空的吗?如果是这样,我如何关闭或读取空元素?
- 如果 element4 是起始元素并且不为空,我正在读取它。如果我删除 (!reader.IsEmptyElement),我会得到一个无限循环。它继续调用 Element4.ReadXml(reader)。为什么是这样?
- 如何修复并继续跳过此问题,以便我可以阅读其余元素。
【问题讨论】:
-
1) 您能否尝试将您的问题简化为minimal reproducible example?它相当复杂但也不完整,因为我们不能只是复制/粘贴到 Visual Studio 中并运行。 2) 你签出stackoverflow.com/questions/279534/…
-
抱歉,我已经尽可能简化了。我已经排除了我用来读写 xml 文件的测试方法。我想到了。我在下面为任何感兴趣的人提供了一个解决方案。大问题的简单解决方案。