xml 如何使用 XPath 忽略命名空间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4440451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to ignore namespaces with XPath
提问by kostja
My goal is to extract certain nodes from multiple xml files with multiple namespaces using XPath. Everything works fine as long as i know the namespace URIs. The namespace name itself remains constant, but the Schemas (XSD) are sometimes client-generated i.e. unknown to me. Then i am left with basically three choices :
我的目标是使用 XPath 从具有多个命名空间的多个 xml 文件中提取某些节点。只要我知道命名空间 URI,一切都可以正常工作。命名空间名称本身保持不变,但架构 (XSD) 有时是客户端生成的,即我不知道。然后我基本上剩下三个选择:
use just one schema for the namespace, hoping nothing goes wrong (can i be sure?)
get the children nodes of the document and look for the first node with a namespace URI, hoping its there and just use the URI , hoping its the correct one. can go wrong for multiple reasons
somehow tell xpath : "look, i dont care about the namespaces, just find ALL nodes with this name, i can even tell you the name of the namespace, just not the URI". And this is the question here...
仅对命名空间使用一种模式,希望不会出错(我可以确定吗?)
获取文档的子节点并查找具有命名空间 URI 的第一个节点,希望它在那里,然后只使用 URI ,希望它是正确的。可能会因为多种原因出错
以某种方式告诉 xpath :“看,我不关心名称空间,只需找到具有此名称的所有节点,我什至可以告诉您名称空间的名称,而不是 URI”。这是这里的问题......
This is not a reiteration of numerous "my xpath expression doesnt work because i am not aware of namespace awareness" questions as found hereor here. I know how to use namespace awareness. Just not how to get rid of it.
这不是在此处或此处找到的众多“我的 xpath 表达式不起作用,因为我不知道名称空间意识”问题的重复。我知道如何使用命名空间意识。只是不知道如何摆脱它。
回答by Dirk Vollmar
You can use the local-name()XPath function. Instead of selecting a node like
您可以使用local-name()XPath 函数。而不是选择一个节点
/path/to/x:somenode
you can select all nodes and filter for the one with the correct local name:
您可以选择所有节点并筛选具有正确本地名称的节点:
/path/to/*[local-name() = 'somenode']
回答by Andrés Cuadros Suárez
You can do the same In XPath2.0in a less verbose syntax:
您可以在XPath2.0中以更简洁的语法执行相同的操作:
/path/to/*:somenode
回答by Pierre Vonderscher
You could use Namespace = false on a XmlTextReader
您可以在 XmlTextReader 上使用 Namespace = false
[TestMethod]
public void MyTestMethod()
{
string _withXmlns = @"<?xml version=""1.0"" encoding=""utf-8""?>
<ParentTag xmlns=""http://anyNamespace.com"">
<Identification value=""ID123456"" />
</ParentTag>
";
var xmlReader = new XmlTextReader(new MemoryStream(Encoding.Default.GetBytes(_withXmlns)));
xmlReader.Namespaces = false;
var content = XElement.Load(xmlReader);
XElement elem = content.XPathSelectElement("/Identification");
elem.Should().NotBeNull();
elem.Attribute("value").Value.Should().Be("ID123456");
}
with :
和 :
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
回答by js2010
Or you can use name():
或者你可以使用 name():
/path/to/*[name() = 'somenode']
Or only search attributes:
或者只搜索属性:
//*[@attribute="this one"]
If you open the xml as a powershell object, it ignores the namespaces:
如果您将 xml 作为 powershell 对象打开,它将忽略命名空间:
[xml]$xml = get-content file.xml
$xml.path.to.somenode

