【问题标题】:Parsing XML stream using LINQ使用 LINQ 解析 XML 流
【发布时间】:2012-05-29 02:21:58
【问题描述】:

我发现了很多关于这个主题的示例和问题,但我尝试过的结果都是空白的。

我需要从 xml 中取出第一个“列表”元素,我只需要 DisplayName 和 Address 信息。

var listings = from c in xdoc.Elements("listing") select c;

【问题讨论】:

    标签: c# xml-parsing linq-to-xml


    【解决方案1】:

    您的查询中缺少命名空间。节点的名字不是listing而是命名空间+listing

    所以需要获取wp元素的命名空间或者使用本地名称属性:

    var listings  = from c in xdoc.Descendants()
                    where c.Name.LocalName == "listing"
                    select c;
    

    或者您需要获取命名空间并将其添加到查询中

    XNamespace ns = // namespace name here
    var listings  = from c in xdoc.Descendants(ns + "listing") select c;
    

    listing 将被定义为IEnumerable<XElement> 的一些变体。确切的类型会因您使用的查询而异,但重要的是它将派生自 IEnumerable<>

    另一个问题是您使用了Elements() 方法。 Elements() 只会搜索由xdoc 定义的节点的子节点。 Descendants() 还将查看子节点的子节点和所有其他子节点。


    更新 1 - 添加了有关从 XML 获取特定节点的更多详细信息

    获取地址和显示名称基本上是相同的过程,实际上您可以将其添加到原始查询中或使用不同的查询(这完全取决于您以后要如何使用它 - 您是否需要其他元素wp:listing 还是 displaynameaddress

    如果您可能需要其他查询,那么将其作为不同的查询似乎是合乎逻辑的,这样您以后可以查询您的结果。可读性也会发挥作用,因为在我看来,将多个查询相互嵌套可能会使其难以阅读。

    获取地址是最难的部分。你需要决定你想要它如何......你想要一个所有地址部分作为子节点的XElement吗?或者你想构造一个新对象?还是你只需要一个串联的字符串?

    但一般查询是这样的:

    var result = from listing in listings
                 select new
                 {
                     Name = listing.Element(ns + "displayname").Value,
                     Address = listing.Element(ns + "address")
                 };
    

    这将为您提供一个IEnumerable<'a'>,其中a 定义为一个匿名类型,由一个名称属性(作为字符串)和一个地址属性(作为XElement)组成。如果你想要别的东西,你必须用适当的代码行替换Address = listing.Element(ns + "address")

    如果您只需要另一个匿名类型,那么您需要在该行中放置一个嵌套查询:

    Address = from part in listing.Elements(ns + "address")
              select new
              {
                  FullStreet = part.Element(ns + "fullstreet").Value,
                  HouseNumber = part.Element(ns + "house").Value,
                  Street = part.Element(ns + "street").Value,
                  StreetType = part.Element(ns + "streettype").Value,
                  // continue for all Elements you need/want
              };
    

    或者您可以创建一个Address 类并在查询中调用构造函数或工厂方法并传递 XElement 或地址部分。

    【讨论】:

    • 我取回了一个对象,但我不能用它做任何事情。
    • 对象是什么意思?列表实际上是object 类型吗?还是IEnumerable<> 的变体?
    • 我已经尝试了我的两种变体,并且在我的编译器中都以IEnumerable<XElement> 的一些变体出现,所以我不确定你的问题出在哪里。您是否从原始查询中获取对象?还是空的IEnumerable<>
    • 非常感谢。我没有正确放置命名空间名称。 (我只放 wp 而不是 uri”
    【解决方案2】:

    尝试使用Descendants 而不是Elements

     var listings = from c in xdoc.Descendants("listing") select c;
    

    【讨论】:

      猜你喜欢
      • 2011-06-13
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 2011-09-05
      • 2016-08-23
      • 1970-01-01
      相关资源
      最近更新 更多