【问题标题】:Get XML element value using XML to Linq使用 XML to Linq 获取 XML 元素值
【发布时间】:2014-11-03 20:38:05
【问题描述】:

XML im 查询的 sn-p 是

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata created="2014-11-03T18:13:02.769Z" xmlns="http://example.com/ns/mmd-2.0#" xmlns:ext="http://example.com/ns/ext#-2.0">
    <customer-list count="112" offset="0">
        <customer id="5f6ab597-f57a-40da-be9e-adad48708203" type="Person" ext:score="100">
            <name>Bobby Smith</name>
            <gender>male</gender>
            <country>US</country>
            <birth-span>
                <start>1965-02-18</start>
                <end>false</end>
            </birth-span>

我为获取元素而编写的代码是

    GetCustomer = from c in XDoc.Descendants(ns + "customer")
                      select
                      new Customer
                      {
                          Name = c.Element(ns + "name").ToString(),
                          Gender = Convert.ToString(c.Element(ns + "gender")),
                          BeginDate = c.Elements("birth-span").Any() ? c.Element("start").Value.ToString() : "No data found"

我遇到的问题是birth-span,如果出生跨度存在,我似乎永远无法获得值(有些记录不包含出生跨度元素)。对于包含birth-span 元素的记录,我添加了不起作用的命名空间变量(抛出对象未设置为实例的错误)

 BeginDate = c.Elements(ns + "birth-span").Any() ? c.Element(ns + "start").Value.ToString() : "No data found"

我添加了不同的变体,但要么我得到值 No Data found 要么一个错误(似乎是对象未设置为实例)。谁能看到我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    您将start 视为c(或customer)的直系后代:

    BeginDate = c.Elements("birth-span").Any() ?
        c.Element("start").Value.ToString() :
        "No data found"
    

    当您真正想要将start 视为birth-span 元素的直接后代时,如下所示:

    BeginDate = c.Elements("birth-span").Any() ?
        c.Element("birth-span").Element("start").Value.ToString() :
        "No data found"
    

    不过还有改进的余地。有零个或一个birth-span 元素,还是零个或多个?由于它似乎是零或一,您可以这样做并使其更清晰:

    var customers = from c in doc.Descendants("customer")
                    let birthSpan = c.Element("birth-span")
                    select new
                    {
                        Name = c.Element("name").Value,
                        Gender = c.Element("gender").Value,
                        BeginDate = birthSpan == null ?
                            "No data found" :
                            birthSpan.Element("start").Value
                    };
    

    此外,您无需致电Convert.ToString.ToString()。如果你想要string.Value() 就可以了。如果您确实希望将其键入其他内容,请直接将其转换并让转换运算符完成工作:

    var customers = from c in doc.Root.Descendants("customer")
                    let birthSpan = c.Element("birth-span")
                    select new
                    {
                        Name = (string)c.Element("name"),
                        Gender = (string)c.Element("gender"),
                        BeginDate = birthSpan == null ?
                            (DateTime?)null :
                            (DateTime?)birthSpan.Element("start")
                    };
    

    关于 here 有一篇很棒的文章。

    【讨论】:

    • Namespace 被包含在...(ns+"customer")
    • 谢谢 - 非常有帮助。在进入高级理论之前,我尝试使用此代码 BeginDate = c.Elements("birth-span").Any() 来获得基本的工作方式? c.Element("birth-span").Element("start").Value.ToString() : "No data found" 但这仍然返回 "No data found"?
    • 您是否按照@Thirisangu 的建议重新添加了ns+?我删除了它们以尝试简化,但它们在您的代码中仍然是必需的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多