LINQ 读取 XML 字符串并放入变量

Posted

技术标签:

【中文标题】LINQ 读取 XML 字符串并放入变量【英文标题】:LINQ to read XML String and put into a variable 【发布时间】:2021-11-28 03:05:27 【问题描述】:

我正在尝试使用 LINQ 读取 XML。以前我使用 XMLDocument 来阅读,但它给出了一个错误,并且 *** 上有人鼓励我使用 LINQ。

下面是我之前用于 XMLDocument 的代码

            string soapmessage = @"<?xml version=""1.0"" encoding=""UTF - 8""?>" + "\n" + response.Content;

            XmlDocument xml = new XmlDocument();
            xml.LoadXml(soapmessage);  //loading soap message as string 

            XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);

            manager.AddNamespace("d", "http://tempuri.org/");
            manager.AddNamespace("bhr", "http://52.187.127.196:5000/api/gsowebservice.asmx");

            XmlNodeList xnList = xml.SelectNodes("//bhr:FourMonthsAhead1Response", manager);
            int nodes = xnList.Count;
            string Status = xnList[0]["FourMonthsAhead1Result"]["PlantForecastIntervals"]["PlantForecastIntervalNode"]["IntervalStartTime"].InnerText;
            Console.WriteLine(Status);
            Console.ReadLine();

我正在尝试将 &lt;IntervalStartTime&gt; 从第一个 &lt;PlantForecastIntervalNode&gt; 获取到日期时间变量中;

下面附上我正在尝试阅读的 XML:

下面是一些 XML 代码。由于代码有 2322 行长,所以我不能在这里粘贴它,所以我将代码缩短为这个。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <s:Body>
        <FourMonthsAhead1Response xmlns="http://tempuri.org/">
            <FourMonthsAhead1Result xmlns="LSS.solar.webservice">
                <PlantDescription xmlns="http://base.datacontract">*PlantName*</PlantDescription>
                <PlantForecastIntervalsCount xmlns="http://base.datacontract">2976</PlantForecastIntervalsCount>
                <ForecastStartDate xmlns="http://base.datacontract">2021-10-08T13:35:55.912612</ForecastStartDate>
                <ForecastEndDate xmlns="http://base.datacontract">2021-10-08T13:35:55.9126123</ForecastEndDate>
                <PlantForecastIntervals xmlns="http://base.datacontract">
                    <PlantForecastIntervalNode>
                        <IntervalStartTime>2021-10-01T00:00:00</IntervalStartTime>
                        <IntervalEndTime>2021-10-01T00:15:00</IntervalEndTime>
                        <IntervalLength>15</IntervalLength>
                        <ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
                        <ForecastValue>0</ForecastValue>
                        <ValueUnit>MW</ValueUnit>
                    </PlantForecastIntervalNode>
                    <PlantForecastIntervalNode>
                        <IntervalStartTime>2021-10-01T00:15:00</IntervalStartTime>
                        <IntervalEndTime>2021-10-01T00:30:00</IntervalEndTime>
                        <IntervalLength>15</IntervalLength>
                        <ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
                        <ForecastValue>0</ForecastValue>
                        <ValueUnit>MW</ValueUnit>
                    </PlantForecastIntervalNode>
                </PlantForecastIntervals>
            </FourMonthsAhead1Result>
        </FourMonthsAhead1Response>
    </s:Body>
</s:Envelope>

更新

在探索 *** 上的其他线程后,我想出了下面这一行,但收到​​另一个错误 System.UriFormatException: 'Invalid URI: The Uri string is too long.':

XDocument xdoc = XDocument.Load(soapmessage);

            var ids = xdoc.Element("FourMonthsAhead1Result")
                 .Elements("PlantForecastIntervals")
                 .Elements("<PlantForecastIntervalNode>")
                 .Select(item => item.Element("IntervalStartTime").Value);
            Console.WriteLine(ids);

【问题讨论】:

哪一行导致错误,错误是什么?请以文本形式提供您的 XML,以防受访者想要复制粘贴并自行测试。 能否请edit 将您的XML 包含为文本 而不是屏幕截图?此处要求不要将图像用于文本数据,请参阅Discourage screenshots of code and/or errorsWhy not upload images of code on SO when asking a question 了解原因。带有不起作用的代码和 XML 的 minimal reproducible example 会增加您获得答案的机会,为什么请参阅 How to Ask。 "您有 C# 问题吗?使用 LINQ!" - 说真的,如果你之前遇到过一些“循环遍历 xml 文档”的问题,那么 LInQ 不太可能是解决方案 我已经编辑并插入了上面的 XML 代码作为文本。对于给您带来的不便,我深表歉意。 你应该迁移到System.Xml.Linqworld。官方文档中的Here 可以是一个好的开始。 【参考方案1】:

使用LINQ试试这个

var response = File.ReadAllText("XMLFile1.xml");
var xe = XElement.Parse(response);
XNamespace ns = "http://base.datacontract";
var obj = xe.Descendants(ns + "PlantForecastIntervals")
            .Descendants(ns + "PlantForecastIntervalNode")
            .Select(x => x.Element(ns + "IntervalStartTime").Value);
Console.WriteLine(obj);

【讨论】:

【参考方案2】:

看看下面的解决方案,

 var xmlRead = File.ReadAllText(@"XMLFile1.xml"); /// Add your xml file path
        var xElement = XElement.Parse(xmlRead);
        XNamespace xNamespace = "http://base.datacontract";
        var obj = xElement.Descendants(xNamespace + "PlantForecastIntervals")
                    .Descendants(xNamespace + "PlantForecastIntervalNode")
                    .Select(x => x.Element(xNamespace + "IntervalStartTime").Value);

        string[] dateTime = obj.ToArray();
    
        foreach (string x in dateTime)
        
            Console.WriteLine(x.ToString()); /// it will print time from all IntervalStartTime tags
        

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。 这个答案的核心——实际检索&lt;IntervalStartTime&gt; 值的LINQ 代码——几乎与Krishna Muppalla's answer 相同;只有一些变量名称不同。另外,obj 是一个IEnumerable&lt;string&gt;,因此您可以直接枚举它,而无需从中创建string[]

以上是关于LINQ 读取 XML 字符串并放入变量的主要内容,如果未能解决你的问题,请参考以下文章

在值中搜索字符串并在 VB.NET 中的 LINQ to XML 中获取属性值

使用 (LINQ/Predicate) 将 DataTable 的所有列名放入字符串数组

从文件中读取字符串并使用 Groovy 将它们放入数组中

如何将 DisplayName 放入变量

动态读取文本文件并放入 C 中的指针字符数组

如何在 C# 中读取此 XML?