我有以下XPath表达式:
/configuration/properties
Run Code Online (Sandbox Code Playgroud)
这是我的XML:
<configuration
xmlns="http://www.ksharma.in/myXSD">
<properties>
<property key="a" value="1" />
<property key="b" value="2" />
</properties>
</configuration>
Run Code Online (Sandbox Code Playgroud)
XPath不起作用.但是,如果我将名称空间更改xmlns为xmlns:conf它的工作原理:
<configuration
xmlns:conf="http://www.ksharma.in/myXSD">
<properties>
<property key="a" value="1" />
<property key="b" value="2" />
</properties>
</configuration>
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
我有一个主题问题的解决方案,但它是一个黑客,我想知道是否有更好的方法来做到这一点.
下面是一个示例XML文件和一个PHP CLI脚本,它执行作为参数给出的xpath查询.对于此测试用例,命令行是:
./xpeg "//MainType[@ID=123]"
Run Code Online (Sandbox Code Playgroud)
最奇怪的是这条线,没有它我的方法不起作用:
$result->loadXML($result->saveXML($result));
Run Code Online (Sandbox Code Playgroud)
据我所知,这只是重新解析修改后的XML,在我看来这不应该是必要的.
有没有更好的方法在PHP中对此XML执行xpath查询?
XML(注意默认命名空间的绑定):
<?xml version="1.0" encoding="utf-8"?>
<MyRoot
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/data http://www.example.com/data/MyRoot.xsd"
xmlns="http://www.example.com/data">
<MainType ID="192" comment="Bob's site">
<Price>$0.20</Price>
<TheUrl><![CDATA[http://www.example.com/path1/]]></TheUrl>
<Validated>N</Validated>
</MainType>
<MainType ID="123" comment="Test site">
<Price>$99.95</Price>
<TheUrl><![CDATA[http://www.example.com/path2]]></TheUrl>
<Validated>N</Validated>
</MainType>
<MainType ID="922" comment="Health Insurance">
<Price>$600.00</Price>
<TheUrl><![CDATA[http://www.example.com/eg/xyz.php]]></TheUrl>
<Validated>N</Validated>
</MainType>
<MainType ID="389" comment="Used Cars">
<Price>$5000.00</Price>
<TheUrl><![CDATA[http://www.example.com/tata.php]]></TheUrl>
<Validated>N</Validated>
</MainType>
</MyRoot>
Run Code Online (Sandbox Code Playgroud)
PHP CLI脚本:
#!/usr/bin/php-cli
<?php
$xml = file_get_contents("xpeg.xml");
$domdoc = new DOMDocument();
$domdoc->loadXML($xml);
// remove the default namespace binding
$e = $domdoc->documentElement;
$e->removeAttributeNS($e->getAttributeNode("xmlns")->nodeValue,"");
// hack hack, cough cough, …Run Code Online (Sandbox Code Playgroud) <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" class="pc chrome win psc_dir-ltr psc_form-xlarge" dir="ltr" lang="en">
<title>Some Title</title>
</html>
Run Code Online (Sandbox Code Playgroud)
如果我跑:
from lxml import etree
html = etree.parse('text.txt')
result = html.xpath('//title')
print(result)
Run Code Online (Sandbox Code Playgroud)
我会得到一个空列表.我想它与命名空间有关,但我无法弄清楚如何解决它.
我正在尝试从 XML 文件中选择节点,但遇到了似乎由命名空间引起的问题。
下面的代码不返回任何内容。但是如果我从 XML 文件中删除命名空间,我会得到预期的结果。
$StandaloneXML = "test.xml"
# Load XML content
$NewStandaloneXML = New-Object -TypeName "System.XML.XMLDocument"
$NewStandaloneXML.Load($StandaloneXML)
# Get namespace
$Namespace = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $NewStandaloneXML.NameTable
$Namespace.AddNamespace("jboss", $NewStandaloneXML.DocumentElement.NamespaceURI)
$NewStandaloneXML.SelectNodes("jboss:server/interfaces/interface", $Namespace)
Run Code Online (Sandbox Code Playgroud)
<?xml version="1.0" ?>
<server xmlns="urn:jboss:domain:4.2">
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
</server>
Run Code Online (Sandbox Code Playgroud)
名称 inet 地址 ---- ------------ 管理 inet-address 公网地址
xpath ×4
xml ×3
domxpath ×1
lxml ×1
namespaces ×1
php ×1
powershell ×1
python ×1
web-scraping ×1
xml-parsing ×1
xsd ×1