简体   繁体   English

C#从XML选择属性或元素

[英]c# select attribute or element from XML

<bookstore>
  <book>
    <bookID>100</bookID>
    <name> The cat in the hat </name>
  </book>
  <book>
    <bookID>90</bookID>
    <name> another book </name>
  </book>
  <book>
    <bookID>103</bookID>
    <name> a new book </name>
  </book>
</bookstore>

I'm trying to sellect the bookID value from a XML document.The method I currently use is Element(bookID).Value But sometimes the bookID comes as an attribute of book like this: <book bookID=100> Is there a way of doing that in c#, like a xPath expression maybe? 我正在尝试从XML文档中出售bookID值。我目前使用的方法是Element(bookID).Value但是有时bookID是这样的book属性: <book bookID=100>有没有办法在c#中做到这一点,也许像xPath表达式? Many thanks! 非常感谢!

Does this need to be an XPath expression or can you use Linq with the XDocument system. 这需要是XPath表达式吗,还是可以将LinqXDocument系统一起使用。

For example. 例如。

var xDocument = XDocument.Parse(@"<bookstore>
                                <book>
                                <bookID>100</bookID>
                                <name> The cat in the hat </name>
                                </book>
                                <book bookID=""90"">
                                <name> another book </name>
                                </book>
                                <book>
                                <bookID>103</bookID>
                                <name> a new book </name>
                                </book>
                                </bookstore>");

foreach (var xBook in xDocument.Descendants("book"))
{
    var bookIdNode = xBook.Elements("bookID").FirstOrDefault();
    int bookId = 0;

    ///there is a book id as an element
    if (bookIdNode != null)
    {
        //invalid book id.. should be an int
        if (!int.TryParse(bookIdNode.Value, out bookId))
            continue;
    }
    else
    {
        var bookIdAttr = xBook.Attributes("bookID").FirstOrDefault();
        if (bookIdAttr == null || !int.TryParse(bookIdAttr.Value, out bookId))
            continue;
    }

    if (bookId == 0)
        continue;

    //else we got our book id

}

This code is quite simple, just enumerates over the descendants with the element name book . 这段代码非常简单,只需使用元素名称book枚举子代即可。 It first checks if there is an element named bookID (case sensitive). 它首先检查是否有一个名为bookID的元素(区分大小写)。 If there is it attempts to parse the book id out as an int using the method int.TryParse() . 如果存在,则尝试使用int.TryParse()方法将图书ID解析为一个int

If there are no bookID elements it next checks if there are any attributes with the name bookID and grabs the first instance (or null) using FirstOrDefault() extension method. 如果没有bookID元素,则接下来检查是否存在名称为bookID属性,并使用FirstOrDefault()扩展方法FirstOrDefault()第一个实例(或null)。 If there is an instance of the bookID attribute it also try to parse the int using the int.TryParse() method. 如果存在bookID属性的实例,它还尝试使用int.TryParse()方法解析int。

By the end of the small snippet we have then check if the bookId is 0 if it is zero we can assume something went wrong. 在小片段的结尾,我们然后检查bookId是否为0如果为零,则可以假设出现问题。 However this shouldnt happen as the logic should keep enumerating and forget about Elements without a bookID element or bookID attribute. 但是,这不应该发生,因为逻辑应继续枚举,并bookID没有bookID元素或bookID属性的Elements。

In XPath, you can use union ( | ) operator to combine query that return different part of the XML. 在XPath中,可以使用union( | )运算符组合返回XML不同部分的查询。 For example : 例如 :

//book/bookID/text() | //book/@bookID

The above XPath returns text content of bookID element and bookID attribute in document order. 上面的XPath按文档顺序返回bookID元素和bookID属性的文本内容。 See the demo which using XmlDocument.SelectNodes() to execute the XPath. 请参见使用XmlDocument.SelectNodes()执行XPath的演示。

Demo Codes : 演示代码

var xml = @"<bookstore>
  <book>
    <bookID>100</bookID>
    <name> The cat in the hat </name>
  </book>
  <book bookID='90'>
    <name> a new book </name>
  </book>
  <book>
    <bookID>103</bookID>
    <name> another book </name>
  </book>
</bookstore>";
var doc = new XmlDocument();
doc.LoadXml(xml);
var result = doc.SelectNodes("//book/bookID/text() | //book/@bookID");
foreach (XmlNode r in result)
{
    Console.WriteLine(r.Value);
}

output : 输出:

100
90
103

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM