XPath 如何处理 XML 命名空间?

2024-01-22

XPath 如何处理 XML 命名空间?

If I use

/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>

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


XPath 1.0/2.0

Defining namespaces in XPath (recommended)

XPath 本身没有办法将名称空间前缀与名称空间绑定。此类设施由托管图书馆提供。

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


以下是 XPath 主机提供的一些用于指定命名空间前缀绑定到命名空间 URI 的各种机制。

(OP's original XPath, /IntuitResponse/QueryResponse/Bill/Id, has been elided to /IntuitResponse/QueryResponse.)

C#:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("i", "http://schema.intuit.com/finance/v3");
XmlNodeList nodes = el.SelectNodes(@"/i:IntuitResponse/i:QueryResponse", nsmgr);

谷歌文档:

很遗憾,IMPORTXML() https://support.google.com/docs/answer/3093342?hl=en不提供命名空间前缀绑定机制。请参阅下一节,击败 XPath 中的命名空间,了解如何使用local-name()作为解决方法。

Java(SAX):

NamespaceSupport support = new NamespaceSupport();
support.pushContext();
support.declarePrefix("i", "http://schema.intuit.com/finance/v3");

Java(XPath):

xpath.setNamespaceContext(new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "i": return "http://schema.intuit.com/finance/v3";
        // ...
       }
    });
  • 记得打电话DocumentBuilderFactory.setNamespaceAware(true) http://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setNamespaceAware%28boolean%29.
  • 也可以看看:Java XPath:使用默认名称空间 xmlns 进行查询 https://stackoverflow.com/questions/10720452/java-xpath-queries-with-default-namespace-xmlns

JavaScript:

See 实现用户定义的命名空间解析器 https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#Implementing_a_User_Defined_Namespace_Resolver:

function nsResolver(prefix) {
  var ns = {
    'i' : 'http://schema.intuit.com/finance/v3'
  };
  return ns[prefix] || null;
}
document.evaluate( '/i:IntuitResponse/i:QueryResponse', 
                   document, nsResolver, XPathResult.ANY_TYPE, 
                   null );

请注意,如果默认命名空间定义了关联的命名空间前缀,则使用nsResolver()由返回Document.createNSResolver() https://developer.mozilla.org/en-US/docs/Web/API/Document/createNSResolver可以消除对客户的需求nsResolver().

Perl (LibXML http://search.cpan.org/dist/XML-LibXML/lib/XML/LibXML/XPathContext.pod):

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 (lxml http://lxml.de/xpathxslt.html#namespaces-and-prefixes):

from lxml import etree
f = StringIO('<IntuitResponse>...</IntuitResponse>')
doc = etree.parse(f)
r = doc.xpath('/i:IntuitResponse/i:QueryResponse', 
              namespaces={'i':'http://schema.intuit.com/finance/v3'})

Python (元素树 https://stackoverflow.com/q/14853243/290085):

namespaces = {'i': 'http://schema.intuit.com/finance/v3'}
root.findall('/i:IntuitResponse/i:QueryResponse', namespaces)

Python (Scrapy http://doc.scrapy.org/en/latest/index.html):

response.selector.register_namespace('i', 'http://schema.intuit.com/finance/v3')
response.xpath('/i:IntuitResponse/i:QueryResponse').getall()

PhP:

改编自@Tomalak 使用 DOMDocument 的回答 https://stackoverflow.com/a/6475568/290085:

$result = new DOMDocument();
$result->loadXML($xml);

$xpath = new DOMXpath($result);
$xpath->registerNamespace("i", "http://schema.intuit.com/finance/v3");

$result = $xpath->query("/i:IntuitResponse/i:QueryResponse");

也可以看看@IMSoP 关于 PHP SimpleXML 命名空间的规范问答 https://stackoverflow.com/q/44894426/290085.

红宝石(野科切):

puts doc.xpath('/i:IntuitResponse/i:QueryResponse',
                'i' => "http://schema.intuit.com/finance/v3")

请注意,Nokogiri 支持删除名称空间,

doc.remove_namespaces!

但请参阅以下警告,阻止破坏 XML 命名空间。

VBA:

xmlNS = "xmlns:i='http://schema.intuit.com/finance/v3'"
doc.setProperty "SelectionNamespaces", xmlNS  
Set queryResponseElement =doc.SelectSingleNode("/i:IntuitResponse/i:QueryResponse")

VB.NET:

xmlDoc = New XmlDocument()
xmlDoc.Load("file.xml")
nsmgr = New XmlNamespaceManager(New XmlNameTable())
nsmgr.AddNamespace("i", "http://schema.intuit.com/finance/v3");
nodes = xmlDoc.DocumentElement.SelectNodes("/i:IntuitResponse/i:QueryResponse",
                                           nsmgr)

SoapUI (doc https://www.soapui.org/docs/functional-testing/validating-messages/validating-xml-messages/):

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

xmlstarlet:

-N i="http://schema.intuit.com/finance/v3"

XSLT:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:i="http://schema.intuit.com/finance/v3">
   ...

一旦声明了命名空间前缀,就可以编写 XPath 来使用它:

/i:IntuitResponse/i:QueryResponse

Defeating namespaces in XPath (not recommended)

另一种方法是编写谓词来测试local-name():

/*[local-name()='IntuitResponse']/*[local-name()='QueryResponse']

或者,在 XPath 2.0 中:

/*:IntuitResponse/*:QueryResponse

以这种方式绕过命名空间是可行的,但不推荐,因为它

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

  • 无法区分不同元素/属性名称 命名空间(命名空间的真正目的)。请注意,可以通过添加额外的谓词来显式检查名称空间 URI 来解决此问题:

     /*[    namespace-uri()='http://schema.intuit.com/finance/v3' 
        and local-name()='IntuitResponse']
     /*[    namespace-uri()='http://schema.intuit.com/finance/v3' 
        and local-name()='QueryResponse']
    

    Thanks to Daniel Haley https://stackoverflow.com/users/317052/daniel-haley for the namespace-uri() note.

  • 过于冗长。

XPath 3.0/3.1

支持现代 XPath 3.0/3.1 的库和工具允许直接在 XPath 表达式中指定命名空间 URI:

/Q{http://schema.intuit.com/finance/v3}IntuitResponse/Q{http://schema.intuit.com/finance/v3}QueryResponse

While Q{http://schema.intuit.com/finance/v3}比使用 XML 命名空间前缀详细得多,它的优点是独立于托管库的命名空间前缀绑定机制。这Q{}符号被称为克拉克符号以它的创始人詹姆斯·克拉克 (James Clark) 命名。 W3C XPath 3.1 EBNF 语法将其称为BracedURILiteral https://www.w3.org/TR/xpath-31/#prod-xpath31-BracedURILiteral.

Thanks to Michael Kay https://stackoverflow.com/users/415448/michael-kay for the suggestion to cover XPath 3.0/3.1's BracedURILiteral.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

XPath 如何处理 XML 命名空间? 的相关文章

随机推荐

  • jQuery/Javascript 暂时禁用 addEventListener/attachEvent 附加的事件

    有没有办法暂时禁用事件侦听器 就我而言 我有一个第三方库 not以 jQuery 为中心 使用以下方法在元素上创建 mouseover mouseout 事件添加事件监听器 附加事件 在某些情况下 另一个事件会在不同的元素上触发 我需要禁用
  • 如何在 R 中保存二值图像的 XY 坐标?

    I am trying to save the XY coordinates of a binary image in R similarly to the save Save XY Coordinates function in Imag
  • 加载前检查文件是否存在

    我想要做的是在 Material Widget 中加载图像以在 ListTile 中使用它 但该资源可能不存在 class MyImage extends StatelessWidget final imagePath MyIcon Str
  • 如何判断多面体是否是凸多面体?

    我正在寻找一种有效的算法来确定多面体是否是凸的 我首先检查欧拉特征是否为 2 我还检查每个面是否都是凸面 但这仍然没有抓住很多案例 看一下这个 http liam flookes com cs geo http liam flookes c
  • 关于 C# RFID 线程的问题

    我的问题是寻求反馈 以确保我采取正确的方法并正确处理线程 我有一种感觉 我可能需要设置一些我自己的线程 所以欢迎所有反馈 我遇到的问题是从零个或多个 RFID 阅读器读取 RFID 标签 我可以毫无问题地为单个读者阅读 因此从多个读者那里阅
  • Django 表单和标题属性

    我需要使用属性 title 来渲染我的表单以进行 jquery 验证 以这种方式渲染我的表单怎么办
  • 自己编码的聊天中的 ListView Rowlayout

    我正在尝试做什么 我正在尝试创建一个必须不同行的聊天 对于每一行我都制作了一个自己的布局文件 但问题是其中一行的布局文件不适合屏幕 Question 我需要在行布局中更改哪些内容才能使其适合应有的效果 您会找到代码以及我正在尝试的打印屏幕
  • 为什么这个函数会多次触发?

    我正在填写这个清单 ul ul 使用 jquery 生成文件夹列表 生成以下 HTML ul li Item 1 li li Item 2 li li Item 3 ul li Sub Item li ul li ul
  • 如何在Jackson ObjectMapper的序列化中添加@JsonIgnore注释字段

    我需要添加 JsonIgnore序列化对象时带注释的字段Jackson ObjectMapper 我知道您可能会建议我删除 JsonIgnore我的类中的注释 但我需要它们在我的应用程序的某些部分可以忽略 在我的应用程序的另一部分我需要那些
  • 滥用比赛?

    您是否会考虑以下代码块匹配滥用 如果是这样 在没有大的 if else if 块的情况下 有什么更优雅的方法可以做到这一点 def sum base Int xs List Int Int base match case 0 gt 1 ca
  • “模糊引用”错误两次指向同一方法

    I used 这个绝妙的解决方案 https stackoverflow com questions 3509290 how to convert a linq result to datatable 3767520 3767520将 li
  • Enterprise Library 5.0安装错误

    此应用程序需要 NET Framework 3 5 SP1 请安装 net Framework 然后再次运行此安装程序 但系统已经安装了 net Framework 4 0 在添加删除程序中我可以看到以下两个条目 1 Microsoft N
  • Angular2:从javascript函数调用组件方法[重复]

    这个问题在这里已经有答案了 目前我正在尝试实现引导日期选择器 它使用jQuery 以及我的 Angular2 项目 这是我到目前为止所拥有的 import Component AfterViewInit Injector Inject fr
  • .ContextMenu 和 .ContextMenuStrip 之间的差异

    两者有什么区别 ContextMenu and ContextMenuStrip在 Windows 窗体中 我已经知道什么是ContextMenu是 但是怎么样ContextMenuStrip不同于ContextMenu 您可能想知道为什么
  • 如何将三角形标记添加到 SpreadsheetGear 网格的任何单元格角?

    这是 SpreadsheetGear Grid 的特定问题 我知道您可以向单元格添加注释 单元格会自动在右上角获得红色三角形标记 但我需要在任何单元格角落添加一个小三角形 不同颜色 来指示一些特殊的东西 有可能做到吗 更新 这是我根据丹尼尔
  • Linux 中 `cd //` 中的双斜杠 // 是什么意思? [复制]

    这个问题在这里已经有答案了 我输入了一个命令cd 代替cd 错误地 而不是像我期望的那样收到错误 shell Bash 显示了一个提示 就像我在 目录
  • 如何在 Keras 中实现 L2-norm pooling?

    我想向我的 CNN 添加一个全局时间池层 它具有三种不同的池函数 均值 最大值和 L2 范数 Keras 有平均池化函数和最大池化函数 但我还没有找到用于 L2 的池化函数 我自己该如何实现呢 我也在寻找这个 keras 中没有这样的开箱即
  • Tensorflow 中的多个会话和图形(在同一进程中)

    我正在训练一个模型 其中输入向量是另一个模型的输出 这涉及从检查点文件恢复第一个模型 同时从头开始初始化第二个模型 使用tf initialize variables 在同一过程中 有大量的代码和抽象 所以我只是将相关部分粘贴到此处 以下是
  • 如何让 Metro(React Native 打包器)忽略某些目录

    Problem 我的项目有一个 providesModule naming collision当试图跑步时react native run ios从命令行 它与自动生成的目录冲突dist 它是由另一个 npm 包 esdoc 创建的 我希望
  • XPath 如何处理 XML 命名空间?

    XPath 如何处理 XML 命名空间 If I use IntuitResponse QueryResponse Bill Id 为了解析下面的 XML 文档 我返回了 0 个节点