【问题标题】:XDocument parses but isnt searchable from stringXDocument 解析但无法从字符串中搜索
【发布时间】:2017-02-20 18:10:07
【问题描述】:

我正在从一个看起来像这样的网站返回一个字符串

<?xml version=\"1.0\" encoding=\"UTF-8\"?><searchResponse requestID=\"500\" status=\"success\"><pso><psoID ID=\"61F2C644-F93A-11DE-8015-73A11AB14291\" targetID=\"mezeoAccount\"><data><email>sholobfc@bluefire.com.au</email><quotaMeg>2048</quotaMeg><quotaUsed>1879736</quotaUsed><active>true</active><unlocked>true</unlocked><allowPublic>true</allowPublic><realm>mezeo</realm><bandwidthQuota>1000000000</bandwidthQuota><billingDay>1</billingDay></data></psoID></pso></searchResponse>"

然后我尝试从中创建一个 XDocument,以便枚举元素

XDocument doc = new XDocument();
doc = XDocument.Parse(respStr);

但是如果我每次都查询元素或后代,它返回 null。我去不了

string s = doc.Element("email").Value;
// or
doc.Descendants("data"); // returns null as well

XDocument.Parse 不返回错误,但我似乎没有可搜索的 xDocument。

任何人都可以看出我所做的事情有什么明显的错误吗?

【问题讨论】:

    标签: linq-to-xml


    【解决方案1】:

    您无需在调用 XDocument.Parse 之前创建新的 XDocument。这不会造成任何问题,只是没有意义。

    但是,这行是错误的,因为 email 不是文档根目录的子节点:

    doc.Element("email").Value;
    

    您的第二个示例看起来不错。这对我有用:

    string s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><searchResponse requestID=\"500\" status=\"success\"><pso><psoID ID=\"61F2C644-F93A-11DE-8015-73A11AB14291\" targetID=\"mezeoAccount\"><data><email>sholobfc@bluefire.com.au</email><quotaMeg>2048</quotaMeg><quotaUsed>1879736</quotaUsed><active>true</active><unlocked>true</unlocked><allowPublic>true</allowPublic><realm>mezeo</realm><bandwidthQuota>1000000000</bandwidthQuota><billingDay>1</billingDay></data></psoID></pso></searchResponse>";
    XDocument doc = XDocument.Parse(s);
    foreach (XElement e in doc.Descendants("data"))
        Console.WriteLine(e);
    

    结果:

    <data>
      <email>sholobfc@bluefire.com.au</email>
      <quotaMeg>2048</quotaMeg>
      <quotaUsed>1879736</quotaUsed>
      <active>true</active>
      <unlocked>true</unlocked>
      <allowPublic>true</allowPublic>
      <realm>mezeo</realm>
      <bandwidthQuota>1000000000</bandwidthQuota>
      <billingDay>1</billingDay>
    </data>
    

    针对您的第二个第三个问题(请参阅此答案的 cmets)试试这个:

    using System;
    using System.Xml.XPath;
    using System.Xml.Linq;
    
    class Program
    {
        public static void Main()
        {
            string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><searchResponse requestID=\"500\" status=\"success\"><pso><psoID ID=\"61F2C644-F93A-11DE-8015-73A11AB14291\" targetID=\"mezeoAccount\"><data><email>sholobfc@bluefire.com.au</email><quotaMeg>2048</quotaMeg><quotaUsed>1879736</quotaUsed><active>true</active><unlocked>true</unlocked><allowPublic>true</allowPublic><realm>mezeo</realm><bandwidthQuota>1000000000</bandwidthQuota><billingDay>1</billingDay></data></psoID></pso></searchResponse>";
            XDocument doc = XDocument.Parse(xml);
            foreach (XElement e in doc.XPathSelectElements("/searchResponse/pso/psoID/data/*"))
                    Console.WriteLine(e);
        }
    }
    

    输出:

    <email>sholobfc@bluefire.com.au</email>
    <quotaMeg>2048</quotaMeg>
    <quotaUsed>1879736</quotaUsed>
    <active>true</active>
    <unlocked>true</unlocked>
    <allowPublic>true</allowPublic>
    <realm>mezeo</realm>
    <bandwidthQuota>1000000000</bandwidthQuota>
    <billingDay>1</billingDay>
    

    【讨论】:

    • 如果我逐步执行相同的示例,我会得到一个输出文本的语句,如您所示。例如,如何让它读取电子邮件字段的值。我想我应该可以去 doc.Element("email").Value; doc.Element("email").Value 不正确吗?
    • 这是不正确的,因为“电子邮件”不是文档根目录的子节点,而是“数据”的子节点。元素仅获取直接子级。如果您也想要孙子,请使用 Descendants("email")。或者您可以使用 XPath:using System.Xml.XPath; ... foreach (XElement e in doc.XPathSelectElements("/searchResponse/pso/psoID/data/email"))。提示:你应该一开始就问这个问题,然后你会马上得到你想要的答案,而不是问两个问题。
    • 抱歉,我不太确定我是否理解。读取数据下所有单个元素的正确方法是什么?我正在尝试 var psoQuery = from pso in doc.Descendants("data") select new MezeoAccount { Email = pso.Element("email").Value, QuotaMeg = Convert.ToInt64(pso.Element("quotaMeg").Value )...但这并没有返回任何东西。我可以通过 Console.Write(doc.Element("searchResponse").Element("pso").Element("psoID").Element("data").Element("email").Value);只是看起来不对。
    • 你又改变了你的问题......这个网站不适合举行讨论。它旨在获得明确定义的问题的答案。你应该先仔细思考,然后问你想回答的问题,尽量避免问你不想回答的问题。尝试回答您的新问题:为什么不使用我上面演示的 XPath,而是从 XPath 中删除 email?恕我直言,这是一个比普通 LINQ 更清洁的解决方案。
    • 我已经针对您的情况发布了 XPath 解决方案的完整源代码。您应该能够将其复制并粘贴进去,它就会起作用。如果这不是您想要的答案,我建议您更仔细地考虑要问什么问题才能得到答案对您有用。尝试在问题中描述您要解决的实际问题。 IE。 '我将如何解析此文档以获取所有电子邮件地址?我试过了,但它抛出了一个空异常。而不是“为什么这段代码会抛出空异常?”第二个问题没有告诉我们您要做什么。
    猜你喜欢
    • 2020-01-27
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多