通过linq获取c#中特定xml元素的值

时间:2015-11-09 14:31:31

标签: c# xml linq

这是在线xml的结果:

<prices targetNamespace="http://api.saxo.com/v1/prices/">
    <price>
        <id>28924741-0-0-1-0-1-0</id>
        <quantity type="integer">1</quantity>
        <normalprice type="decimal">49,95</normalprice>
        <price type="decimal">49,95</price>
        <vatpercent type="decimal">25,00</vatpercent>
        <fixedprice>false</fixedprice>
        <discount type="decimal">0,00</discount>
        <allowdiscount type="integer">1</allowdiscount>
        <productid>28924741</productid>
        <entries>
            <entry>
                <id>1</id>
                <type type="PriceEntryType">Standard</type>
                <quantity type="integer">1</quantity>
                <vatpercent type="decimal">25,00</vatpercent>
                <vatamount type="decimal">9,99</vatamount>
                <priceunitexvat type="decimal">39,96</priceunitexvat>
                <priceunitinclvat type="decimal">49,95</priceunitinclvat>
                <pricetotalexvat type="decimal">39,96</pricetotalexvat>
                <pricetotalinclvat type="decimal">49,95</pricetotalinclvat>
                <discountpercent type="decimal">0,00</discountpercent>
                <discountamountexvat type="decimal">0,00</discountamountexvat>
                <discountamountinclvat type="decimal">0,00</discountamountinclvat>
            </entry>
            <entry>
                <id>2</id>
                <type type="PriceEntryType">Context</type>
                <quantity type="integer">1</quantity>
                <vatpercent type="decimal">25,00</vatpercent>
                <vatamount type="decimal">9,99</vatamount>
                <priceunitexvat type="decimal">39,96</priceunitexvat>
                <priceunitinclvat type="decimal">49,95</priceunitinclvat>
                <pricetotalexvat type="decimal">39,96</pricetotalexvat>
                <pricetotalinclvat type="decimal">49,95</pricetotalinclvat>
                <discountpercent type="decimal">0,00</discountpercent>
                <discountamountexvat type="decimal">0,00</discountamountexvat>
                <discountamountinclvat type="decimal">0,00</discountamountinclvat>
            </entry>
            <entry>
                <id>3</id>
                <type type="PriceEntryType">Subscription</type>
                <quantity type="integer">1</quantity>
                <vatpercent type="decimal">25,00</vatpercent>
                <vatamount type="decimal">6,99</vatamount>
                <priceunitexvat type="decimal">27,96</priceunitexvat>
                <priceunitinclvat type="decimal">34,95</priceunitinclvat>
                <pricetotalexvat type="decimal">27,96</pricetotalexvat>
                <pricetotalinclvat type="decimal">34,95</pricetotalinclvat>
                <discountpercent type="decimal">30,03</discountpercent>
                <discountamountexvat type="decimal">12,00</discountamountexvat>
                <discountamountinclvat type="decimal">15,00</discountamountinclvat>
            </entry>
        </entries>
    </price>
</prices>

我尝试了很多方法来获得最后一个条目的“normalprice”和“pricetotalinclvat”的价值。但我得到了空或异常。

你能指导我如何使用linq获得这两个值吗?

5 个答案:

答案 0 :(得分:1)

看起来可能是this的重复 简短版本是:

XElement element = XElement.Parse(YourString);
var prices = element.Elements("price")
          .Select(item => item.Element("normalprice").Value);

答案 1 :(得分:1)

可以使用Descendant结合Last

提取这些值
  var xml = XElement.Parse(xmlStr);

  var normalPrice = xml
    .Descendants("normalprice")
    .Last()
    .Value;

  var pricetotalinclvat = xml
    .Descendants("pricetotalinclvat")
    .Last()
    .Value;

答案 2 :(得分:1)

你可以试试这个:

 XDocument doc = XDocument.Load(path);
 var query = from price in doc.Descendants("price")
             select new
                        {
                           NormalPrice = price.Element("normalprice").Value,
                           PriceTotalInclVat = price.Descendants("entry").Last().Element("pricetotalinclvat").Value
                        };

如果您没有条目,可以避免出现空例外,您也可以这样做:

var query = from price in doc.Descendants("price")
            select new
                      {
                         NormalPrice = price.Element("normalprice").Value,
                         PriceTotalInclVat = price.Descendants("entry").Any()?price.Descendants("entry").Last().Element("pricetotalinclvat").Value:"0"
                      };

或者:

var query = from price in doc.Descendants("price")
            let entries = price.Descendants("entry")
            select new
                       {
                         NormalPrice = price.Element("normalprice").Value,
                         PriceTotalInclVat = entries!=null ? entries.Last().Element("pricetotalinclvat").Value : "0"
                       };

答案 3 :(得分:1)

如果方法无关紧要,在这种情况下,将内容加载到XDocument并通过XPath访问似乎更有意义:

您希望将System.Xml.XPath命名空间与此...

一起使用
    System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Parse(xmlString);
    decimal priceNormal = 0;
    decimal.TryParse(xdoc.XPathSelectElement(@"/prices/price/normalprice").Value, out priceNormal);
    decimal priceTotalInclvat = 0;
    decimal.TryParse(xdoc.XPathSelectElement(@"/prices/price/entry[last()]/pricetotalinclvat").Value, out priceTotalInclvat);

答案 4 :(得分:0)

我尝试了此页面中的所有解决方案,但我没有得到任何结果。它真是太奇怪了。这就是我所做的,但这不是一个好方法:

  var document = XDocument.Load(url);
        var root = document.Root;

        if (root == null)
            return;

        var ns = root.GetDefaultNamespace();
        var mainNode = document.Element(ns + "prices");

        if (mainNode == null)
        return;


            var priceNode = mainNode.Elements(ns + "price").FirstOrDefault().Elements();
            var lastEntry = mainNode.Elements(ns + "price").FirstOrDefault().Elements().Last().Elements().Last().Elements();


            foreach (var element in lastEntry.Where(element => element.Name.LocalName == "pricetotalinclvat"))
            {
                plusPrice = element.Value;
            }

            foreach (var element in priceNode.Where(xElement => xElement.Name.LocalName == "price"))
            {
                price = element.Value;
            }

有什么建议可以让它变得更好吗?