简体   繁体   English

在XML文件中测试XPath的最佳方法是什么?

[英]Best way test for XPath existence in an XML file?

Lately I've been using XPathDocument and XNavigator to parse an XML file for a given XPath and attribute. 最近我一直在使用XPathDocument和XNavigator来解析给定XPath和属性的XML文件。 It's been working very well, when I know in advance what the XPath is. 当我事先知道XPath是什么时,它工作得非常好。

Sometimes though, the XPath will be one of several possible XPath values, and I'd like to be able to test whether or not a given XPath exists. 有时候,XPath将是几个可能的XPath值之一,我希望能够测试给定的XPath是否存在。

In case I'm getting the nomenclature wrong, here's what I'm calling an XPath - given this XML blob: 如果我的命名法错了,这就是我所谓的XPath - 给定这个XML blob:

<foo>
    <bar baz="This is the value of the attribute named baz">
</foo>

I might be looking for what I'm calling an XPath of "//foo/bar" and then reading the attribute "baz" to get the value. 我可能正在寻找我称之为“// foo / bar”的XPath,然后读取属性“baz”来获取值。

Example of the code that I use to do this: 我用来执行此操作的代码示例:

XPathDocument document = new XPathDocument(filename);
XPathNavigator navigator = document.CreateNavigator();
XPathNavigator node = navigator.SelectSingleNode("//foo/bar");
if(node.HasAttributes)
{
    Console.WriteLine(node.GetAttribute("baz", string.Empty));
}

Now, if the call to navigator.SelectSingleNode fails, it will return a NullReferenceException or an XPathException. 现在,如果对navigator.SelectSingleNode的调用失败,它将返回NullReferenceException或XPathException。 I can catch both of those and refactor the above into a test to see whether or not a given XPath returns an exception, but I was wondering whether there was a better way? 我可以捕获这两个并重构上面的测试,以查看给定的XPath是否返回异常,但我想知道是否有更好的方法?

I didn't see anything obvious in the Intellisense. 我没有在Intellisense中看到任何明显的东西。 XPathNavigator has .HasAttributes and .HasChildren but short of iterating through the path one node at a time, I don't see anything nicer to use. XPathNavigator有.HasAttributes和.HasChildren但是没有一次遍历一个节点的路径,我没有看到任何更好的使用。

If you've given valid XPath but it doesn't match anything, SelectSingleNode won't throw a NullReferenceException - it will just return null. 如果你给出了有效的XPath,但它没有匹配, SelectSingleNode不会抛出 NullReferenceException - 它只会返回null。

If you pass SelectSingleNode some syntactically invalid XPath, that's when it will throw an XPathException . 如果你传递SelectSingleNode一些语法上无效的XPath,那就是它会抛出一个XPathException

So normally, you'd just need to test whether the returned value was null or not. 通常,您只需要测试返回值是否为null。

 var baz = navigator.SelectSingleNode("//foo/bar/@baz");
 if (baz != null) Console.WriteLine(baz);

I think it is not good to create an XMLNode object by executing navigator.SelectSingleNode(...). 我认为通过执行navigator.SelectSingleNode(...)来创建XMLNode对象并不好。

You have to use navigator.Evaluate() instead: 你必须使用navigator.Evaluate()代替:

if (Convert.ToBoolean(navigator.Evaluate(@"boolean(//foo/bar)"))) {...}

From memory, may contain errors. 从内存中,可能包含错误。

XDocument doc = XDocument.Load("foo.xml");

var att = from a in doc.Descendants("bar")
          select a.Attribute("baz")

foreach (var item in att) {
    if (item != null) { ... }
}

If node == null then node.HasAttributes will throw a NullReferenceException . 如果node == nullnode.HasAttributes将抛出NullReferenceException This situation will occur when //foo/bar does not match any elements in the XML document. //foo/bar与XML文档中的任何元素都不匹配时,就会出现这种情况。

var node = XDocument.Load(filename)
                    .Descendants("bar")
                    .SingleOrDefault(e=>e.Attribute("baz") != null);

if (node != null) Console.WriteLine(node.Attribute("baz").Value);

I would probably be more specific in my xpath. 我可能在我的xpath中更具体。

        var doc = XDocument.Load(fileName);

        var results = from r in doc.XPathSelectElements("/foo/bar[count(@baz) > 0]")
                      select r.Attribute("baz");

        foreach (String s in results)
            Console.WriteLine(s);

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

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