[英]Using XPath to extract XML in PHP
我有以下XML:
<root>
<level name="level1">
<!-- More children <level> -->
</level>
<level name="level2">
<!-- Some more children <level> -->
</level>
</root>
如何直接在<root>
下提取<level>
以便可以相对于提取的<level>
运行XPath查询,例如$xml->xpath('//some-query')
?
DOMXpath::evaluate()
允许您从DOM中获取节点列表和标量值。
因此,您可以使用Xpath表达式直接获取值:
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
var_dump(
$xpath->evaluate('string(/root/level[@name="level2"]/@name)')
);
输出:
string(6) "level2"
root
所有level
元素节点:
/root/level
具有特定的名称属性:
/root/level[@name="level2"]
您要获取的值(用于验证的name
属性):
/root/level[@name="level2"]/@name
强制转换为字符串,如果找到节点,则结果将为空字符串:
string(/root/level[@name="level2"]/@name)
如果需要为该节点执行多个表达式,则最好单独获取它并使用foreach()
更好。 DOMXpath::evaluate()
的第二个参数是上下文节点。
foreach ($xpath->evaluate('/root/level[@name="level2"]') as $level) {
var_dump(
$xpath->evaluate('string(@name)', $level)
);
}
如果需要处理未找到任何节点,则可以检查DOMNodeList::$length
属性。
$levels = $xpath->evaluate('/root/level[@name="level2"]');
if ($levels->length > 0) {
$level = $levels->item(0);
var_dump(
$xpath->evaluate('string(@name)', $level)
);
} else {
// no level found
}
您也可以使用count()
表达式来验证这里是否包含元素。
var_dump(
$xpath->evaluate('count(/root/level[@name="level2"])')
);
输出:
float(1)
可以在Xpath中将该条件作为条件并返回布尔值。
var_dump(
$xpath->evaluate('count(/root/level[@name="level2"]) > 0')
);
输出:
bool(true)
DOMXPath :: query的第二个参数是上下文节点。 只需传递先前“已找到”的DOMNode实例,查询就可以“相对”运行到该节点。 例如
<?php
$doc = new DOMDocument;
$doc->loadxml( data() );
$xpath = new DOMXPath($doc);
$nset = $xpath->query('/root/level[@name="level1"]');
if ( $nset->length < 1 ) {
die('....no such element');
}
else {
$elLevel = $nset->item(0);
foreach( $xpath->query('c', $elLevel) as $elC) {
echo $elC->nodeValue, "\r\n";
}
}
function data() {
return <<< eox
<root>
<level name="level1">
<c>C1</c>
<a>A</a>
<c>C2</c>
<b>B</b>
<c>C3</c>
</level>
<level name="level2">
<!-- Some more children <level> -->
</level>
</root>
eox;
}
但是除非您必须执行多个单独的(可能是复杂的)后续查询,否则很有可能没有必要
<?php
$doc = new DOMDocument;
$doc->loadxml( data() );
$xpath = new DOMXPath($doc);
foreach( $xpath->query('/root/level[@name="level1"]/c') as $c ) {
echo $c->nodeValue, "\r\n";
}
function data() {
return <<< eox
<root>
<level name="level1">
<c>C1</c>
<a>A</a>
<c>C2</c>
<b>B</b>
<c>C3</c>
</level>
<level name="level2">
<c>Ahh</c>
<a>ouch</a>
<c>no</c>
<b>wrxl</b>
</level>
</root>
eox;
}
仅使用一个查询就具有相同的输出。
这应该工作:
$dom = new DOMDocument;
$dom->loadXML($xml);
$levels = $dom->getElementsByTagName('level');
foreach ($levels as $level) {
$levelname = $level->getAttribute('name');
if ($levelname == 'level1') {
//do stuff
}
}
我个人更喜欢使用DOMNodeList类来解析XML。
使用querypath解析XML / HTML使得这一切变得非常容易。
$qp = qp($xml) ;
$levels = $qp->find('root')->eq(0)->find('level') ;
foreach($levels as $level ){
//do whatever you want with it , get its xpath , html, attributes etc.
$level->xpath() ; //
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.