簡體   English   中英

使用PHP和xpath獲取祖先節點

[英]Get ancestor node with PHP and xpath

請原諒如果以下有點混亂,我一直在努力解決這個問題。

這是我用來為mini-CMS創建類別樹的一大塊XML(從一個大型站點導出)。 一旦我獲得了節點的值和名稱,這沒有問題,我還需要獲得每個節點的“父”,即層次結構中位於它之上的節點。

    <productCategory>
    <genericName>DigitalCinema</genericName>
    <productCategories>
      <productCategory>
        <genericName>DCinemaProj</genericName>
        <productModels>
          <productModel>ProjProd-1</productModel>
          <productModel>ProjProd-2</productModel>
          <productModel>ProjProd-3</productModel>
          <productModel>ProjProd-4</productModel>
        </productModels>
      </productCategory>
      <productCategory>
        <genericName>DCinemaLens</genericName>
      </productCategory>
    </productCategories>
  </productCategory>

例如,對於productCategory-genericName DCinemaLens ,我需要能夠將父級抓取為DigitalCinema ,對於單個productModel節點,其中父級將是DCinemaProj

我已經嘗試使用祖先,前兄弟和父親在xpath中進行各種不同的查詢,但我仍然看不到抓住我需要的節點。

這是我的代碼,因為幾分鍾前放棄了我的嘗試。

if ($xml->xpath('//productCategories')) {

    foreach($xml->xpath('//genericName | //productModel') as $genericName){

    echo "<p align='center'>$genericName";

    $type = $genericName->getName();

    echo " - (" . $type . ") ";

    $derp = $xml->xpath("ancestor::productCategory[1]/genericName");

    echo $derp;

    echo '</p>';

    }

    }

我在數組中獲取信息也取得了一些成功,但它總是只返回XML中的每個值。

$key = 'genericName';

    $derpgleep = $derp[$key];

    echo 'Derp= ' . $derpgleep;

    print_r($derp);

希望我能忽略一個非常簡單的解決方案。 我希望我已經清楚了。

您正在使用的XPath表達式:

 ancestor::productCategory[1]/genericName

如果你能夠從當前節點開始執行該表達式將會工作。 從當前的Array $genericName開始,這是不可能的,因為它不包含父類,也不包含祖先。

我認為您的選擇是重新遍歷所有XML樹。 這是一個樣本測試,根據您的輸入樣本,根據需要運行。

<?php
$xml = simplexml_load_file("test_input1.xml");

if ($xml->xpath('//productCategories')) {

    foreach($xml->xpath('//genericName') as $genericName){

        echo "<p align='center'>$genericName";

        $type = $genericName->getName();

        echo " - (" . $type . ") ";

        $derp = $xml->xpath("//genericName[.='" . 
            $genericName[0] . 
            "']/ancestor::productCategory[2]/genericName");

        echo $derp[0];  echo "</p>\n";
    }
}
?>

這將打印出以下HTML片段:

<p align='center'>DigitalCinema - (genericName) </p>
<p align='center'>DCinemaProj - (genericName) DigitalCinema</p>
<p align='center'>DCinemaLens - (genericName) DigitalCinema</p>

要獲得productModel的“父”,您需要一個xpath,如:

        $derp = $xml->xpath("//productModel[.='" . 
            $productModel[0] . 
            "']/parent::productCategory[1]/genericName");

使用 (假設初始上下文節點是productCategory[genericName = 'DCinemaLens']productModel ):

../preceding-sibling::*[1]

基於XSLT的驗證

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*/*/productCategory
            [genericName = 'DCinemaLens']
               /../preceding-sibling::*[1]"/>
-------------
<xsl:text/>
  <xsl:copy-of select=
  "/*/*/*/*/productModel/../preceding-sibling::*[1]"/>
 </xsl:template>
</xsl:stylesheet>

當此轉換應用於提供的XML文檔時

<productCategory>
    <genericName>DigitalCinema</genericName>
    <productCategories>
        <productCategory>
            <genericName>DCinemaProj</genericName>
            <productModels>
                <productModel>ProjProd-1</productModel>
                <productModel>ProjProd-2</productModel>
                <productModel>ProjProd-3</productModel>
                <productModel>ProjProd-4</productModel>
            </productModels>
        </productCategory>
        <productCategory>
            <genericName>DCinemaLens</genericName>
        </productCategory>
    </productCategories>
</productCategory>

想要的兩個元素被復制到輸出

<genericName>DigitalCinema</genericName>
-------------
<genericName>DCinemaProj</genericName>

暫無
暫無

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

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