2017-01-02 99 views
0

我有一個問題...我想重命名一些XML文件中的標籤。在它的工作原理與此代碼:(XML)PHP是不是重命名所有標籤?

$xml = file_get_contents('data/onlinekeystore.xml'); 
renameTags($xml, 'priceEUR', 'price', 'data/onlinekeystore.xml'); 

但如果我要重新命名另一個XML文件,它好好嘗試工作,用同樣的方法... 請參見下面的例子。我不知道爲什麼... 有人有一個想法,可以幫助我嗎?

$xml = file_get_contents('data/g2a.xml'); 
renameTags($xml, 'name', 'title', 'data/g2a.xml'); 

功能代碼:

function renameTags($xml, $old, $new, $path){ 
    $dom = new DOMDocument(); 
    $dom->loadXML($xml); 

    $nodes = $dom->getElementsByTagName($old); 
    $toRemove = array(); 
    foreach ($nodes as $node) { 
     $newNode = $dom->createElement($new); 
     foreach ($node->attributes as $attribute) { 
      $newNode->setAttribute($attribute->name, $attribute->value); 
     } 

     foreach ($node->childNodes as $child) { 
      $newNode->appendChild($node->removeChild($child)); 
     } 

     $node->parentNode->appendChild($newNode); 
     $toRemove[] = $node; 
    } 

    foreach ($toRemove as $node) { 
     $node->parentNode->removeChild($node); 
    } 

    $dom->saveXML(); 
    $dom->save($path); 
} 

onlinekeystore.xml輸入:

<product> 
    <priceEUR>5.95</priceEUR> 
</product> 

onlinekeystore.xml輸出繼電器:

<product> 
    <price>5.95</price> 
</product> 

g2a.xml輸入:

<products> 
    <name><![CDATA[1 Random STEAM PREMIUM CD-KEY]]></name> 
</products> 

g2a.xml輸出繼電器:

<products> 
    <name><![CDATA[1 Random STEAM PREMIUM CD-KEY]]></name> 
</products> 

問候

+1

我測試過這個,它對我來說工作正常。你有什麼錯誤嗎?你得到了什麼結果?你運行的是哪個版本的php? – CUGreen

+0

我正在使用PHPStorm和PHP 7.1。我沒有得到任何錯誤...這就是奇怪 – Jan

回答

0

考慮動態XSLT運行Identity Transform然後更新節點名稱在一個特定的模板中的任何地方文件。 sprintf格式的XSL字符串傳入$old$new值。這個過程避免了整個樹的任何嵌套循環,甚至無論輸入的格式如何都輸出相當的輸出。

function renameTags($xml, $old, $new, $path){ 
    // LOAD XML 
    $dom = new DOMDocument(); 
    $dom->loadXML($xml); 

    // LOAD XSL 
    $xslstr = '<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output version="1.0" encoding="UTF-8" indent="yes" method="xml" cdata-section-elements="%2$s"/> 
    <xsl:strip-space elements="*"/> 

     <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
     </xsl:template> 

     <xsl:template match="%1$s"> 
     <xsl:element name="%2$s">    
      <xsl:apply-templates/> 
     </xsl:element> 
     </xsl:template> 

    </xsl:transform>'; 
    $xsl = new DOMDocument(); 
    $xsl->loadXML(sprintf($xslstr, $old, $new)); 

    // INITIALIZE TRANSFORMER (REQUIRES php_xsl EXTENSION ENABLED IN .ini) 
    $proc = new XSLTProcessor; 
    $proc->importStyleSheet($xsl); 

    // TRANSFORM XML AND SAVE OUTPUT 
    $newXML = $proc->transformToXML($dom); 
    file_put_contents($path, $newXML); 
} 

輸出

renameTags('<product><priceEUR>5.95</priceEUR></product>', 'priceEUR', 'price', 'data/onlinekeystore.xml'); 

// <?xml version="1.0" encoding="UTF-8"?> 
// <product> 
// <price><![CDATA[5.95]]></price> 
// </product>  

renameTags('<products><name><![CDATA[1 Random STEAM PREMIUM CD-KEY]]></name></products>', 'name', 'title', 'data/g2a.xml'); 

// <?xml version="1.0" encoding="UTF-8"?> 
// <products> 
// <title><![CDATA[1 Random STEAM PREMIUM CD-KEY]]></title> 
// </products> 

注:在XSLT中,<![CDATA[...]]標籤不會保留,除非<xsl:output>明確指定。現在,任何新節點的文本都與它一起包裝了。刪除輸出規範並且不顯示CData標記。所以要麼全部包含這樣的轉義標籤,要麼沒有。

+0

我試過你的代碼,但它不工作... – Jan

+0

什麼是行不通的?什麼錯誤?注意註釋(初始化轉換器),我提到你需要在你的.ini文件中啓用php_xsl擴展。 – Parfait