如何使用 xpath (php) 查询 xml 文件?
How to query a xml file using xpath (php) ?
我正在尝试使用 XPath 查询 XML 文件。但是作为 return 我什么也得不到。我想我将查询格式化为 false。
XML
<subject id="Tom">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
PHP
$xpath = new DOMXpath($doc);
$role = 'ITSupporter';
$elements = $xpath-> query("//subject/@id[../relation/@role='".$role."']");
foreach ($elements as $element) {
$name = $element -> nodeValue;
$arr[$i] = $name;
$i = $i + 1;
}
如何获取 ID TOM?我想将它保存到例如 $var
试试这个 XPath
//subject[relation/@role='".$role."']/@id
您在 id
属性而不是 subject
元素上应用谓词。
通过id获取元素与通过$role内容获取元素是一样的。
所以,像下面这样;
$xpath->query("//*[@id='$id']")->item(0);
换句话说,@id 应该在'['括号内。
构建 Xpath 表达式:
- 获取任何
subject
元素
//subject
- ... 带有子元素
relation
//subject[relation]
- ... 具有给定文本的
role
属性
//subject[relation/@role="ITSupporter"]
- ...并得到
subject
//subject[relation/@role="ITSupporter"]/@id
的@id
属性
此外,可以清理源代码。 PHP 数组可以使用 $array[]
语法将新元素推入其中。
放在一起:
$xml = <<<'XML'
<subject id="Tom">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$ids = [];
foreach ($xpath->evaluate("//subject[relation/@role='".$role."']/@id") as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);
输出:
array(1) {
[0]=>
string(3) "Tom"
}
如果您只需要一个结果,您可以在 Xpath 中转换它:
$id = $xpath->evaluate(
"string(//subject[relation/@role='".$role."']/@id)"
);
var_dump($id);
输出:
string(3) "Tom"
XML 命名空间
查看评论中发布的示例,您的 XML 使用没有前缀的命名空间 http://cpee.org/ns/organisation/1.0
。 XML 解析器将解析它,因此您可以将节点读取为 {http://cpee.org/ns/organisation/1.0}subject
。这里有 3 个例子,都解决了这个问题:
<subject xmlns="http://cpee.org/ns/organisation/1.0"/>
<cpee:subject xmlns:cpee="http://cpee.org/ns/organisation/1.0"/>
<c:subject xmlns:c="http://cpee.org/ns/organisation/1.0"/>
Xpath 表达式也必须如此。然而 Xpath 没有
默认命名空间。您需要注册一个使用您选择的前缀。这个
允许 Xpath 引擎将 //org:subject
解析为 //{http://cpee.org/ns/organisation/1.0}subject
.
PHP不需要改动太多:
$xml = <<<'XML'
<subject id="Tom" xmlns="http://cpee.org/ns/organisation/1.0">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// register a prefix for the namespace
$xpath->registerNamespace('org', 'http://cpee.org/ns/organisation/1.0');
$ids = [];
// address the elements using the registered prefix
$idAttributes = $xpath->evaluate("//org:subject[org:relation/@role='".$role."']/@id");
foreach ($idAttributes as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);
我正在尝试使用 XPath 查询 XML 文件。但是作为 return 我什么也得不到。我想我将查询格式化为 false。
XML
<subject id="Tom">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
PHP
$xpath = new DOMXpath($doc);
$role = 'ITSupporter';
$elements = $xpath-> query("//subject/@id[../relation/@role='".$role."']");
foreach ($elements as $element) {
$name = $element -> nodeValue;
$arr[$i] = $name;
$i = $i + 1;
}
如何获取 ID TOM?我想将它保存到例如 $var
试试这个 XPath
//subject[relation/@role='".$role."']/@id
您在 id
属性而不是 subject
元素上应用谓词。
通过id获取元素与通过$role内容获取元素是一样的。
所以,像下面这样;
$xpath->query("//*[@id='$id']")->item(0);
换句话说,@id 应该在'['括号内。
构建 Xpath 表达式:
- 获取任何
subject
元素//subject
- ... 带有子元素
relation
//subject[relation]
- ... 具有给定文本的
role
属性//subject[relation/@role="ITSupporter"]
- ...并得到
subject
//subject[relation/@role="ITSupporter"]/@id
的
@id
属性
此外,可以清理源代码。 PHP 数组可以使用 $array[]
语法将新元素推入其中。
放在一起:
$xml = <<<'XML'
<subject id="Tom">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$ids = [];
foreach ($xpath->evaluate("//subject[relation/@role='".$role."']/@id") as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);
输出:
array(1) {
[0]=>
string(3) "Tom"
}
如果您只需要一个结果,您可以在 Xpath 中转换它:
$id = $xpath->evaluate(
"string(//subject[relation/@role='".$role."']/@id)"
);
var_dump($id);
输出:
string(3) "Tom"
XML 命名空间
查看评论中发布的示例,您的 XML 使用没有前缀的命名空间 http://cpee.org/ns/organisation/1.0
。 XML 解析器将解析它,因此您可以将节点读取为 {http://cpee.org/ns/organisation/1.0}subject
。这里有 3 个例子,都解决了这个问题:
<subject xmlns="http://cpee.org/ns/organisation/1.0"/>
<cpee:subject xmlns:cpee="http://cpee.org/ns/organisation/1.0"/>
<c:subject xmlns:c="http://cpee.org/ns/organisation/1.0"/>
Xpath 表达式也必须如此。然而 Xpath 没有
默认命名空间。您需要注册一个使用您选择的前缀。这个
允许 Xpath 引擎将 //org:subject
解析为 //{http://cpee.org/ns/organisation/1.0}subject
.
PHP不需要改动太多:
$xml = <<<'XML'
<subject id="Tom" xmlns="http://cpee.org/ns/organisation/1.0">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// register a prefix for the namespace
$xpath->registerNamespace('org', 'http://cpee.org/ns/organisation/1.0');
$ids = [];
// address the elements using the registered prefix
$idAttributes = $xpath->evaluate("//org:subject[org:relation/@role='".$role."']/@id");
foreach ($idAttributes as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);