使用 XmlReader 如何读取空元素?
Using XmlReader how do I read past an empty element?
我使用 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 文件。这就是它中断的地方。它可以很好地读取 element、element1、element2 和 element3。但是,当涉及到 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)。为什么是这样?
- 如何解决并继续解决这个问题,以便我可以阅读其余元素。
在我从 xml 文件中读取元素的地方,我需要添加另一个 else if 条件来处理元素是否为起始元素以及元素是否为空。我只是在检查它是否不是空的。所以它不知道如何处理它是空的。然后,当满足这些条件时,我只需执行 reader.Read() 即可告诉应用程序按原样读取元素 <element4/>
。
这是它的样子:
else if (reader.IsStartElement("element4")) && (reader.IsEmptyElement))
{
reader.Read();
}
我使用 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 文件。这就是它中断的地方。它可以很好地读取 element、element1、element2 和 element3。但是,当涉及到 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)。为什么是这样?
- 如何解决并继续解决这个问题,以便我可以阅读其余元素。
在我从 xml 文件中读取元素的地方,我需要添加另一个 else if 条件来处理元素是否为起始元素以及元素是否为空。我只是在检查它是否不是空的。所以它不知道如何处理它是空的。然后,当满足这些条件时,我只需执行 reader.Read() 即可告诉应用程序按原样读取元素 <element4/>
。
这是它的样子:
else if (reader.IsStartElement("element4")) && (reader.IsEmptyElement))
{
reader.Read();
}