如何告诉XMLReader不要读取空元素

时间:2016-01-01 15:48:13

标签: c# xml xmlreader

我正在解析一些不包含自闭元素的旧XML数据。

所有元素都有终结元素

[a]

当我使用C#中的XMLReader解析文件时,读者会对start-tag和end-tag中的任何“空内容”执行额外的.Read()。

当我将比赛添加到列表中时,我总是获得想要的内容,并且我的列表中添加了空白内容。

我可以通过调用

来解决问题
<my-element someValue="xyz"></my-element>
<!-- instead of <my-element someValue"xyz" /> -->

在我的循环结束时手动,但如果我遇到一些包含自动关闭标签的数据文件,那就相当hacky了。

如何告诉读者跳过所有空元素?

UPDATE:

如果我放

,它就有效
reader.Skip(); 

位于我的

顶部
 if(reader.IsStartElement()){...

循环

2 个答案:

答案 0 :(得分:1)

我的2美分使这个可重复使用,并希望透明。

public class NoEmptyElementsXmlReader : XmlReaderWrapper
{
    public NoEmptyElementsXmlReader(XmlReader xmlReader)
        : base(xmlReader)
    { }

    public override bool Read()
    {
        bool success = base.Read();

        while (IsEmptyElement && success)
        {
            success = base.Read();
        }

        return success;
    }
}

使用它像:

var reader = new NoEmptyElementsXmlReader(XmlReader.Create(stream));

通用包装类:

public abstract class XmlReaderWrapper : XmlReader
{
    private readonly XmlReader _reader;

    protected XmlReaderWrapper(XmlReader xmlReader)
    {
        _reader = xmlReader;
    }

    protected XmlReader InternalReader
    {
        get { return _reader; }
    }

    public override XmlNodeType NodeType
    {
        get { return _reader.NodeType; }
    }

    public override string LocalName
    {
        get { return _reader.LocalName; }
    }

    public override string NamespaceURI
    {
        get { return _reader.NamespaceURI; }
    }

    public override string Prefix
    {
        get { return _reader.Prefix; }
    }

    public override string Value
    {
        get { return _reader.Value; }
    }

    public override int Depth
    {
        get { return _reader.Depth; }
    }

    public override string BaseURI
    {
        get { return _reader.BaseURI; }
    }

    public override bool IsEmptyElement
    {
        get { return _reader.IsEmptyElement; }
    }

    public override int AttributeCount
    {
        get { return _reader.AttributeCount; }
    }

    public override bool EOF
    {
        get { return _reader.EOF; }
    }

    public override ReadState ReadState
    {
        get { return _reader.ReadState; }
    }

    public override XmlNameTable NameTable
    {
        get { return _reader.NameTable; }
    }

    public override string GetAttribute(string name)
    {
        return _reader.GetAttribute(name);
    }

    public override string GetAttribute(string name, string namespaceURI)
    {
        return _reader.GetAttribute(name, namespaceURI);
    }

    public override string GetAttribute(int i)
    {
        return _reader.GetAttribute(i);
    }

    public override string LookupNamespace(string prefix)
    {
        return _reader.LookupNamespace(prefix);
    }

    public override bool MoveToAttribute(string name)
    {
        return _reader.MoveToAttribute(name);
    }

    public override bool MoveToAttribute(string name, string ns)
    {
        return _reader.MoveToAttribute(name, ns);
    }

    public override bool MoveToElement()
    {
        return _reader.MoveToElement();
    }

    public override bool MoveToFirstAttribute()
    {
        return _reader.MoveToFirstAttribute();
    }

    public override bool MoveToNextAttribute()
    {
        return _reader.MoveToNextAttribute();
    }

    public override bool ReadAttributeValue()
    {
        return _reader.ReadAttributeValue();
    }

    public override void ResolveEntity()
    {
        _reader.ResolveEntity();
    }

    public override bool Read()
    {
        return _reader.Read();
    }
}

答案 1 :(得分:0)

您可以使用 reader.IsStartElement 来检查元素是否为空。

    while (reader.Read()) {

  if (reader.IsStartElement()) {
if (reader.IsEmptyElement)
  Console.WriteLine("<{0}/>", reader.Name);
else {
  Console.Write("<{0}> ", reader.Name);
  reader.Read(); // Read the start tag.
  if (reader.IsStartElement())  // Handle nested elements.
    Console.Write("\r\n<{0}>", reader.Name);
  Console.WriteLine(reader.ReadString());  //Read the text content of the element.
}

} }