我已經使用XmlWriter編寫了一個Xml文件。 下面是代碼:使用XmlReader如何讀取過去的空元素?
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();
}
正如你可以看到,元素4呼籲 「中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");
}
}
注意,如果元素4 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."
所以我的問題是:
- 這是因爲該元素是空的?如果是這樣,我該如何關閉或閱讀一個空的元素?
- 我正在讀元素4,如果它是開始元素,如果它不是空的....如果我刪除(!reader.IsEmptyElement)我得到一個無限循環。它繼續調用Element4.ReadXml(reader)。爲什麼是這樣?
- 如何修復並繼續過去,以便我可以讀取其餘的元素。
有人嗎?思考? – Tim
1)你可以嘗試簡化你的問題到[mcve]嗎?這很複雜,但也不完整,因爲我們不能複製/粘貼到Visual Studio中並運行。 2)你有沒有簽出https://stackoverflow.com/questions/279534/proper-way-to-implement-ixmlserializable – dbc
對不起,但這是儘可能簡化,因爲我可以做到這一點。我已經排除了用於讀取和寫入xml文件的測試方法。我想到了。我已經爲任何感興趣的人提供了一個解決方案簡單的解決一個大問題。 – Tim