草庐IT

php - SimpleXML 中用于默认 namespace 的 XPath,无需前缀

coder 2024-01-01 原文

我有一个 XML 文档,它附加了一个默认的命名空间,例如

<foo xmlns="http://www.example.com/ns/1.0">
...
</foo>

实际上,这是一个符合复杂模式的复杂 XML 文档。我的工作是从中解析出一些数据。为了帮助我,我有一个 XPath 电子表格。 XPath 嵌套很深,例如

level1/level2/level3[@foo="bar"]/level4[@foo="bar"]/level5/level6[2]

生成 XPath 的人是模式方面的专家,所以我假设我无法简化它,或者使用对象遍历快捷方式。

我正在使用 SimpleXML解析一切。我的问题与默认 namespace 的处理方式有关。

因为在根元素上有一个默认的命名空间,我不能这样做

$xml = simplexml_load_file($somepath);
$node = $xml->xpath('level1/level2/level3[@foo="bar"]/level4[@foo="bar"]/level5/level6[2]');

我必须register the namespace ,将其分配给一个前缀,然后在我的 XPath 中使用该前缀,例如

$xml = simplexml_load_file($somepath);
$xml->registerXPathNamespace('myns', 'http://www.example.com/ns/1.0');
$node = $xml->xpath('myns:level1/myns:level2/myns:level3[@foo="bar"]/myns:level4[@foo="bar"]/myns:level5/myns:level6[2]');

从长远来看,添加前缀是不可管理的。

是否有一种无需使用 XPath 前缀即可处理默认 namespace 的正确方法?

使用空前缀不起作用 ($xml->registerXPathNamespace('', 'http://www.example.com/ns/1.0');)。我可以串出默认的命名空间,eg

$xml = file_get_contents($somepath);
$xml = str_replace('xmlns="http://www.example.com/ns/1.0"', '', $xml);
$xml = simplexml_load_string($xml);

但这是在回避问题。

最佳答案

从一些在线阅读来看,这并不局限于任何特定的 PHP 或其他库,而是 XPath 本身——至少在 XPath 1.0 版中是这样

XPath 1.0 不包含任何“默认”命名空间的概念,因此无论元素名称如何出现在 XML 源中,如果它们绑定(bind)了命名空间,则它们的选择器必须在基本 XPath 选择器中添加前缀形式为 ns:name。请注意,ns 是在 XPath 处理器中定义的前缀,而不是由正在处理的文档定义的,因此与 xmlns 属性在 XML 表示中的使用方式无关。

参见例如this "common XSLT mistakes" page ,谈论密切相关的 XSLT 1.0:

To access namespaced elements in XPath, you must define a prefix for their namespace. [...] Unfortunately, XSLT version 1.0 has no concept similar to a default namespace; therefore, you must repeat namespace prefixes again and again.

根据 an answer to a similar question , XPath 2.0 确实包含“默认 namespace ”的概念,并且上面链接的 XSLT 页面也在 XSLT 2.0 的上下文中提到了这一点。

不幸的是,PHP 中的所有内置 XML 扩展都是构建在 libxml2 之上的和 libxslt库,仅支持 1.0 版的 XPath 和 XSLT。

因此,除了预处理文档以不使用命名空间之外,您唯一的选择是找到一个可以插入 PHP 的 XPath 2.0 处理器。

(顺便说一句,值得注意的是,如果您的 XML 文档中有未加前缀的属性,它们在技术上不在默认 namespace 中,而是根本不在任何 namespace 中;参见 XML Namespaces and Unprefixed Attributes用于讨论命名空间规范的这种奇怪之处。)

关于php - SimpleXML 中用于默认 namespace 的 XPath,无需前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21143846/

有关php - SimpleXML 中用于默认 namespace 的 XPath,无需前缀的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  3. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  4. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  5. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  6. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  7. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  8. ruby-on-rails - capybara ::ElementNotFound:无法找到 xpath "/html" - 2

    我正在学习http://ruby.railstutorial.org/chapters/static-pages上的RubyonRails教程并遇到以下错误StaticPagesHomepageshouldhavethecontent'SampleApp'Failure/Error:page.shouldhave_content('SampleApp')Capybara::ElementNotFound:Unabletofindxpath"/html"#(eval):2:in`text'#./spec/requests/static_pages_spec.rb:7:in`(root)'

  9. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  10. Ruby 默认将 IRB 配置为 Pretty_Inspect - 2

    我是ruby​​的新手,正在配置IRB。我喜欢pretty-print(需要'pp'),但总是输入pp来漂亮地打印它似乎很麻烦。我想做的是默认情况下让它漂亮地打印出来,所以如果我有一个var,比如说,'myvar',然后键入myvar,它会自动调用pretty_inspect而不是常规检查。我从哪里开始?理想情况下,我将能够向我的.irbrc文件添加一个自动调用的方法。有什么想法吗?谢谢! 最佳答案 irb中默认pretty-print对象正是hirb被迫去做。Theseposts解释hirb如何将几乎所有内容转换为ascii表。虽

随机推荐