[英]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表达式吗,还是可以将Linq
与XDocument
系统一起使用。
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.