【问题标题】:How to tell XMLReader not to read empty Elements如何告诉 XMLReader 不要读取空元素
【发布时间】:2016-01-01 15:48:13
【问题描述】:

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

所有元素也都有结束元素

<my-element someValue="xyz"></my-element>
<!-- instead of <my-element someValue"xyz" /> -->

当我在 C# 中使用 XMLReader 解析文件时,阅读器会为开始标记和结束标记中的任何“空内容”执行额外的 .Read()。

当我将比赛添加到列表中时,我总是会得到想要的内容,而我的列表中会添加一个空内容。

我可以通过调用来解决这个问题

reader.Skip(); 

在我的循环结束时手动操作,但如果我遇到一些包含自闭标签的数据文件,那就太麻烦了。

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

更新:

如果我放一个就可以了

 if(reader.IsStartElement()){...

在我的顶部

while(reader.Read()){ ... 

循环

【问题讨论】:

  • 我认为这是不可能的。您可以判断一个元素是否会自动关闭,因为XmlReader.IsEmptyElement 将是true。我想你可以弄清楚在你的循环中做什么。
  • 刚刚找到一个解决方案:我正在通过 reader.IsStartElement(); 进行检查

标签: c# xml xmlreader


【解决方案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();
    }
}

【讨论】:

    【解决方案2】:

    您可以使用 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.
    }
    

    } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 2011-03-09
      • 1970-01-01
      • 2019-03-08
      • 2013-07-30
      相关资源
      最近更新 更多