使用XmlReader如何读取空元素?

时间:2016-07-21 15:55:39

标签: c# xml xmlreader

我使用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。如果为null,则应将此元素写为空元素。在这种情况下,p.CurrentValue为null所以我想要一个空元素。您将在下面的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文件的方法。这就是它中断的地方。它确实很好的读取元素,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是空的,所以这个方法永远不会被调用。所以当它到达reader.ReadEndElement()时,它将继续执行else {}语句并中断。我得到的错误信息是:

"Message: TestMethod myTestMethodName threw exception: System.Xml.XmlException 'Element' is an invalid XmlNodeType. Line 8, position 6."  

所以我的问题是:

  1. 这是因为元素是空的吗?如果是这样,我如何关闭或读取空元素?
  2. 我正在读取element4,如果它是start元素,如果它不是空的....如果我删除(!reader.IsEmptyElement)我得到一个无限循环。它继续调用Element4.ReadXml(读者)。为什么是这样?
  3. 如何修复并继续浏览,以便我可以阅读其余元素。

1 个答案:

答案 0 :(得分:1)

在我从我的xml文件中读取我的元素时,如果元素是start元素并且元素为空,我需要添加另一个if if to handle。我只是检查它是否是空的。所以它不知道如何处理它是空的。然后,当满足这些条件时,我只需要执行reader.Read()告诉应用程序按原样<element4/>读取元素。

这是它的样子:

else if (reader.IsStartElement("element4")) && (reader.IsEmptyElement))
    {
        reader.Read();
    }