将xml节点重复到单独的块中

时间:2019-04-07 20:31:50

标签: php xml

我有这样的xml:

<products>
 <product>
 <name>ad</name>
 <category>something</category>
 ...
    <size>S</size>
    <color-code>87-3</color-code>
    <size-code>24294</size-code>
    <size-qty>10</size-qty>
    <size-codeproducer>5902228002604</size-codeproducer>
    <size>M</size>
    <color-code>87-4</color-code>
    <size-code>24295</size-code>
    <size-qty>64</size-qty>
    <size-codeproducer>5902228002611</size-codeproducer>
    <size>L</size>
    <color-code>87-5</color-code>
    <size-code>24296</size-code>
    <size-qty>46</size-qty>
    <size-codeproducer>5902228002628</size-codeproducer>
    <size>XXL</size>
    <color-code>87-7</color-code>
    <size-code>24298</size-code>
    <size-qty>0</size-qty>
    <size-codeproducer>5902228002635</size-codeproducer>
  </product>
  <product>
  ...
  ...
  ...
  </product>
</products>

好吧,我想将<size><color-code>和其他类似的重复节点分开:

<product>
<name>ad</name>
<category>something</category>
...
<variation>
   <size>S</size>
   <color-code>87-3</color-code>
   <size-code>24294</size-code>
   <size-qty>10</size-qty>
   <size-codeproducer>5902228002604</size-codeproducer>
</variation>
<variation>
   <size>M</size>
   <color-code>87-4</color-code>
   <size-code>24295</size-code>
   <size-qty>64</size-qty>
   <size-codeproducer>5902228002611</size-codeproducer>
</variation>
<variation>
   <size>L</size>
   <color-code>87-5</color-code>
   <size-code>24296</size-code>
   <size-qty>46</size-qty>
   <size-codeproducer>5902228002628</size-codeproducer>
</variation>
<variation>
   <size>XXL</size>
   <color-code>87-7</color-code>
   <size-code>24298</size-code>
   <size-qty>0</size-qty>
   <size-codeproducer>5902228002635</size-codeproducer>
</variation>

我真的想不出一个很好的逻辑来做到这一点。我正在使用php,第一件事是我虽然正在使用数组并检查节点是否存在,并始终检查大小节点是否存在-如果它确实创建了一个新数组。什么是最好和最简单的方法?

1 个答案:

答案 0 :(得分:2)

请考虑XSLT,这是一种专用语言(如SQL),旨在转换XML文件,例如您的特定最终用途需求。与许多通用语言一样,PHP可以使用特殊的库(类似于php-xsl类(需要启用.ini扩展名),使用特殊的库将XSLT 1.0作为较低层运行。

具体来说,下面的XSLT通过循环遍历每个 size (假定它将始终开始 variation 分组)来重写每个 product 节点(以进行检索)相同的节点对应的节点。

XSLT (另存为.xsl文件,一个特殊的.xml文件)

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

     <xsl:template match="products">
        <xsl:copy>
            <xsl:apply-templates select="product"/>
        </xsl:copy>
     </xsl:template>

     <xsl:template match="product">
        <xsl:copy>
            <xsl:variable name="prod_pos" select="position()"/>
            <xsl:copy-of select="name|category"/>
            <xsl:for-each select="size">
                <variation>
                    <xsl:variable name="size_occur" select="position()"/>
                        <xsl:copy-of select="."/>
                        <xsl:copy-of select="/products/product[$prod_pos]/color-code[$size_occur]"/>
                        <xsl:copy-of select="/products/product[$prod_pos]/size-code[$size_occur]"/>
                        <xsl:copy-of select="/products/product[$prod_pos]/size-qty[$size_occur]"/>
                        <xsl:copy-of select="/products/product[$prod_pos]/size-codeproducer[$size_occur]"/>
                </variation>
            </xsl:for-each>
        </xsl:copy>
     </xsl:template>

</xsl:stylesheet>

PHP

// Load the XML source and XSLT file
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xml->load('Input.xml');

$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');

// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
echo $newXML;

// Save output to file
$xmlfile = 'Output.xml';
file_put_contents($xmlfile, $newXML);

输出

<products>
   <product>
      <name>ad</name>
      <category>something</category>
      <variation>
         <size>S</size>
         <color-code>87-3</color-code>
         <size-code>24294</size-code>
         <size-qty>10</size-qty>
         <size-codeproducer>5902228002604</size-codeproducer>
      </variation>
      <variation>
         <size>M</size>
         <color-code>87-4</color-code>
         <size-code>24295</size-code>
         <size-qty>64</size-qty>
         <size-codeproducer>5902228002611</size-codeproducer>
      </variation>
      <variation>
         <size>L</size>
         <color-code>87-5</color-code>
         <size-code>24296</size-code>
         <size-qty>46</size-qty>
         <size-codeproducer>5902228002628</size-codeproducer>
      </variation>
      <variation>
         <size>XXL</size>
         <color-code>87-7</color-code>
         <size-code>24298</size-code>
         <size-qty>0</size-qty>
         <size-codeproducer>5902228002635</size-codeproducer>
      </variation>
   </product>
</products>

XSLT Demo