Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XPath如何处理XML名称空间?_Xml_Xpath_Xml Namespaces - Fatal编程技术网

XPath如何处理XML名称空间?

XPath如何处理XML名称空间?,xml,xpath,xml-namespaces,Xml,Xpath,Xml Namespaces,XPath如何处理XML名称空间? 如果我使用 /IntuitResponse/QueryResponse/Bill/Id 要解析下面的XML文档,我返回了0个节点 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2016-10-14T10:48:3

XPath如何处理XML名称空间?

如果我使用

/IntuitResponse/QueryResponse/Bill/Id
要解析下面的XML文档,我返回了0个节点

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" 
                time="2016-10-14T10:48:39.109-07:00">
    <QueryResponse startPosition="1" maxResults="79" totalCount="79">
        <Bill domain="QBO" sparse="false">
            <Id>=1</Id>
        </Bill>
    </QueryResponse>
</IntuitResponse>

=1
但是,我没有在XPath中指定名称空间(即
http://schema.intuit.com/finance/v3
不是路径的每个标记的前缀)。如果我没有明确告诉XPath,它怎么知道我想要哪个
Id
?我认为在这种情况下(因为只有一个名称空间),XPath可以完全忽略
xmlns
。但是如果有多个名称空间,事情可能会变得糟糕。

用XPath定义名称空间(推荐) XPath本身没有将名称空间前缀与名称空间绑定的方法。这些设施由托管图书馆提供

建议您使用这些工具并定义名称空间前缀,然后根据需要使用这些前缀来限定XML元素和属性名称


下面是XPath主机为指定命名空间URI的命名空间前缀绑定而提供的一些机制

(OP的原始XPath,
/IntuitResponse/QueryResponse/Bill/Id
,已被省略为
/IntuitResponse/QueryResponse

C#:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
XmlNamespaceManager nsmgr=新的XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace(“i”http://schema.intuit.com/finance/v3");
XmlNodeList nodes=el.SelectNodes(@“/i:IntuitResponse/i:QueryResponse”,nsmgr);
Java(SAX):

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
NamespaceSupport=new NamespaceSupport();
support.pushContext();
支持。declarePrefix(“i”http://schema.intuit.com/finance/v3");
Java(XPath):

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
xpath.setNamespaceContext(新的NamespaceContext(){
公共字符串getNamespaceURI(字符串前缀){
开关(前缀){
案例“一”:返回http://schema.intuit.com/finance/v3";
// ...
}
});
  • 记得打电话
  • 另见:
JavaScript:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
见:

函数nsResolver(前缀){
变量ns={
'我':'http://schema.intuit.com/finance/v3'
};
返回ns[前缀]| | null;
}
document.evaluate(“/i:IntuitResponse/i:QueryResponse”,
文档,nsResolver,XPathResult.ANY_类型,
无效);
Perl():

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
my$xc=XML::LibXML::XPathContext->new($doc);
$xc->registerNs('i','http://schema.intuit.com/finance/v3');
my@nodes=$xc->findnodes('/i:IntuitResponse/i:QueryResponse');
Python():

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
从lxml导入etree
f=StringIO(“…”)
doc=etree.parse(f)
r=doc.xpath(“/i:IntuitResponse/i:QueryResponse”,
名称空间={'i':'http://schema.intuit.com/finance/v3'})
Python():

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
namespace={'i':'http://schema.intuit.com/finance/v3'}
root.findall('/i:IntuitResponse/i:QueryResponse',名称空间)
Python():

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
response.selector.register\u名称空间('i','http://schema.intuit.com/finance/v3')
xpath('/i:IntuitResponse/i:QueryResponse').getall()
PhP:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
改编自:

$result=newDOMDocument();
$result->loadXML($xml);
$xpath=newdomxpath($result);
$xpath->registerNamespace(“i”http://schema.intuit.com/finance/v3");
$result=$xpath->query(“/i:IntuitResponse/i:QueryResponse”);
另见

Ruby(Nokogiri):

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
put doc.xpath('/i:IntuitResponse/i:QueryResponse',
'我'=>“http://schema.intuit.com/finance/v3")
请注意,Nokogiri支持删除名称空间

doc.remove\u名称空间!
但是请参见下面的警告,这些警告阻止了XML名称空间的失败

VBA:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
xmlNS=“xmlNS:i=”http://schema.intuit.com/finance/v3'"
doc.setProperty“SelectionNamespaces”,xmlNS
设置queryResponseElement=doc.SelectSingleNode(“/i:IntuitResponse/i:QueryResponse”)
VB.NET:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
xmlDoc=newxmldocument()
Load(“file.xml”)
nsmgr=新的XmlNamespaceManager(新的XmlNameTable())
nsmgr.AddNamespace(“i”http://schema.intuit.com/finance/v3");
nodes=xmlDoc.DocumentElement.SelectNodes(“/i:IntuitResponse/i:QueryResponse”,
国家安全经理)
SoapUI():

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
xmlstarlet:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse
-ni=”http://schema.intuit.com/finance/v3"
XSLT:

declare namespace i='http://schema.intuit.com/finance/v3';
/i:IntuitResponse/i:QueryResponse

...
请注意,如果默认命名空间定义了关联的命名空间前缀,则使用返回的
nsResolver()
可以避免使用客户
nsResolver()


声明名称空间前缀后,可以编写XPath以使用它:

/i:IntuitResponse/i:QueryResponse

在XPath中破坏名称空间(不推荐) 另一种方法是编写针对
local-name()
进行测试的谓词:

或者,在XPath 2.0中:

/*:IntuitResponse/*:QueryResponse
以这种方式绕过名称空间是可行的,但不建议这样做,因为它

  • 下指定完整的元素/属性名称

  • 无法区分不同类型中的元素/属性名称 名称空间(名称空间的用途)。请注意,可以通过添加附加谓词来明确检查名称空间URI 1来解决此问题:

    1感谢提供
    名称空间-uri()
    注释

  • 太冗长了

我在google工作表中使用
/*[name()='…']
从Wikidata获取一些计数。我有一个这样的表

 thes    WD prop links   items
 NOM     P7749   3925    3789
 AAT     P1014   21157   20224
cols
链接
项目
中的公式为

=IMPORTXML("https://query.wikidata.org/sparql?query=SELECT(COUNT(*)as?c){?item wdt:"&$B14&"[]}","//*[name()='literal']")
=IMPORTXML("https://query.wikidata.org/sparql?query=SELECT(COUNT(distinct?item)as?c){?item wdt:"&$B14&"[]}","//*[name()='literal']")
SPARQL查询恰好没有任何空格

我在中看到使用了
name()
而不是
local-name()
,出于某种原因
/*:literal
不起作用