使用名称空间使selectnode对大写或小写不敏感

时间:2017-10-24 04:24:28

标签: c# xml xpath xml-namespaces selectsinglenode

我有以下XML:

<myfile:bookstore>
<myfile:books>
<myfile:book> Book 1</myfile:book>
<myfile:book> Book 2</myfile:book>
</myfile:books>
</myfile:bookstore>

以下代码选择<myfile:books>节点:

XmlNamespaceManager nsmgr = new 
XmlNamespaceManager(el.OwnerDocument.NameTable);
nsmgr.AddNamespace("myfile", 
el.OwnerDocument.DocumentElement.NamespaceURI);

var node = el.SelectSingleNode(@"/myfile:bookstore/myfile:books", nsmgr);

如果节点名称myfile:boOkSmyfile:BOOKS对大写和小写不敏感,如何使其工作?

另一个问题是我的namespaceManager吗?可以更简单吗?

1 个答案:

答案 0 :(得分:0)

您可以使用local-name()namespace-uri()函数在XPath查询中返回元素名称和名称空间,然后使用translate()函数来小写本地名称。

因此以下内容应该有效:

var elementName = "books"; // Or whatever
var nameSpaceUri = el.OwnerDocument.DocumentElement.NamespaceURI;
var xpathQuery = string.Format(@"/myfile:bookstore/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='{0}' and namespace-uri()='{1}']", elementName, nameSpaceUri);
var node = el.SelectSingleNode(xpathQuery, nsmgr);

示例工作.Net fiddle

请注意,在这种情况下,应避免使用较小的name()函数返回值。例如。你可能想要做以下事情:

var node = el.SelectSingleNode(@"/myfile:bookstore/*[translate(name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'myfile:books']", nsmgr);

但是,不应使用,因为它会在字符串文字myfile:中对命名空间前缀 'myfile:books'进行硬编码。如果稍后输入XML被修改为使用不同的前缀 - 或根本没有前缀,例如:

<bookstore xmlns="http://MyRootNameSpace">
  <Books>
    <Book> Book 1</Book>
    <Book> Book 2</Book>
  </Books>
</bookstore>

然后,尽管新XML在语义上与旧XML相同,但您的XPath查询仍会中断。