【问题标题】:read repetitive blocks using XmlReader c#使用 XmlReader c# 读取重复块
【发布时间】:2016-06-02 15:11:48
【问题描述】:

我有以下 xml 文件:

<PackList>
  <Header>
    <OrderNumber>PO12123</OrderNumber>
    <OrderQty>100</OrderQty>
  </Header>
  <Items>
    <Item>
      <PN>31023312</PN>
      <Color>Black</Color>
    </Item>
    <Item>
      <PN>22023312</PN>
      <Color>White</Color>
    </Item>
    <Item>
      <PN>44023312</PN>
      <Color>Blue</Color>
    </Item>
  </Items>
</PackList>

我可以使用以下代码读取Header 部分:

public class OrderItem
{
    public string PN { get; set; }
    public string Color { get; set; }
}

public class PList
{
    public string OrderNumber { get; set; }
    public int OrderQty { get; set; }
    public List<OrderItem> OrderItems = new List<OrderItem>();
}

(...)
PList PL = new PList();
using (XmlReader reader = XmlReader.Create(@"c:/Test/PackList.xml"))
{
    reader.ReadToFollowing("OrderNumber");
    PList.OrderNumber = reader.ReadElementContentAsString();
    reader.ReadToFollowing("OrderQty");
    PList.OrderQty = reader.ReadElementContentAsInt();
}
(...)

但我不知道如何读取Items 标记中的每个Item

有什么建议吗?

【问题讨论】:

标签: c# xml xmlreader


【解决方案1】:
reader.ReadToFollowing("OrderNumber");
plist.OrderNumber = reader.ReadElementContentAsString();
reader.ReadToFollowing("OrderQty");
plist.OrderQty = reader.ReadElementContentAsInt();

reader.ReadToFollowing("Items");

using (var innerReader = reader.ReadSubtree())
{
    while (innerReader.ReadToFollowing("PN"))
    {
        var item = new OrderItem();
        item.PN = innerReader.ReadElementContentAsString();
        reader.ReadToFollowing("Color");
        item.Color = innerReader.ReadElementContentAsString();

        plist.OrderItems.Add(item);
    }
}

reader.ReadToFollowing("foo");
var foo = reader.ReadElementContentAsString();

其中fooItems 之后的标签名称。

别忘了plist.OrderItems = new List&lt;OrderItem&gt;();

【讨论】:

  • 我正在测试您发布的相同方法,它工作正常。但是,如果在 Items 之后有另一个标签(不是发布的案例),它将不会被读取,因为 ReadToFollowing("PN") 如果为 false,则 XmlReader 处于文件结束状态。
【解决方案2】:

使用 XmlNodeList

XmlDocument document = new XmlDocument();

document.Load(@"c:/Test/PackList.xml");

XmlNodeList Items = document.GetElementsByTagName("Item");

foreach (XmlNode item in Items)
{
    // do something
}

【讨论】:

  • 这会将整个文档拉入内存。 XmlReader 是“firehose”方式。
  • 如果可能的话,我想用 XmlReader 来做。
【解决方案3】:

查看 XmlReader。ReadSubtree() 方法。

返回一个新的 XmlReader 实例,该实例可用于读取当前 节点及其所有后代。

https://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readsubtree(v=vs.110).aspx

注意:主阅读器的位置也可能会移动,因此您将继续在不完全是 ReadToFollowing() 得到的位置。

【讨论】:

    猜你喜欢
    • 2019-03-08
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2023-03-30
    • 1970-01-01
    • 2010-11-07
    相关资源
    最近更新 更多