簡體   English   中英

使用XPath在PHP中提取XML

[英]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"

Xpath表達式

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()表達式

您也可以使用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() ; //
}

Querypath的優秀初學者教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM