从XML节点获取数据


Getting data from XML nodes

我是PHP和XML的初学者。

我有一个XML文件如下(部分):

<combination>
  <id_combination>2289</id_combination>
  <quantity>4</quantity>
  <unit_price_impact>0.000000</unit_price_impact>
  <reference>K10100.1B</reference>
  <group_name>Color</group_name>
  <attribute_name>Blue</attribute_name>
</combination>
<combination>
  <id_combination>2289</id_combination>
  <quantity>4</quantity>
  <unit_price_impact>0.000000</unit_price_impact>
  <reference>K10100.1B</reference>
  <group_name>Size</group_name>
  <attribute_name>1</attribute_name>
</combination>
<combination>
  <id_combination>2290</id_combination>
  <quantity>20</quantity>
  <unit_price_impact>0.000000</unit_price_impact>
  <reference>K10100.2B</reference>
  <group_name>Color</group_name>
  <attribute_name>Blue</attribute_name>
</combination>
<combination>
  <id_combination>2290</id_combination>
  <quantity>20</quantity>
  <unit_price_impact>0.000000</unit_price_impact>
  <reference>K10100.2B</reference>
  <group_name>Size</group_name>
  <attribute_name>2</attribute_name>
</combination>

和我希望得到一个数组如下所示:

$id_combination => 2289
$reference => K10100.1B
$combination_name => Color: Blue / Size: 1
$quantity => 4
$id_combination => 2290
$reference => K10100.2B
$combination_name => Color: Blue / Size: 2
$quantity => 20

我想用相同的'id_combination'节点连接数据,然后在PHP中处理它。

我尝试使用"foreach"循环,"array_unique","implode"等。但没能取得任何成功。

我将感谢任何人帮助我直接结果与建议的代码。

我只是对您的XML做了以下更改,并添加了新的代码和外观,并在我的xampp服务器上工作

$xml='<?xml version="1.0" encoding="UTF8"?>
        <combinations>
            <combination>
              <id_combination>2289</id_combination>
              <quantity>4</quantity>
              <unit_price_impact>0.000000</unit_price_impact>
              <reference>K10100.1B</reference>
              <group_name>Color</group_name>
              <attribute_name>Blue</attribute_name>
            </combination>
            <combination>
              <id_combination>2289</id_combination>
              <quantity>4</quantity>
              <unit_price_impact>0.000000</unit_price_impact>
              <reference>K10100.1B</reference>
              <group_name>Size</group_name>
              <attribute_name>1</attribute_name>
            </combination>
            <combination>
              <id_combination>2290</id_combination>
              <quantity>20</quantity>
              <unit_price_impact>0.000000</unit_price_impact>
              <reference>K10100.2B</reference>
              <group_name>Color</group_name>
              <attribute_name>Blue</attribute_name>
            </combination>
            <combination>
              <id_combination>2290</id_combination>
              <quantity>20</quantity>
              <unit_price_impact>0.000000</unit_price_impact>
              <reference>K10100.2B</reference>
              <group_name>Size</group_name>
              <attribute_name>2</attribute_name>
            </combination>
        </combinations>';
        $xmlobject = simplexml_load_string($xml);
        echo '<pre>';
        // this print an array of objects
        print_r($xmlobject);
        // this print the associative array
        print_r((array)$xmlobject);

考虑一个XSLT解决方案,因为这是XSLT 1.0中Muenchian Method的典型需求,该方法用于按各种键对节点进行分组。作为信息,XSLT是一种专门用于转换XML文件的语言,与大多数通用语言一样,PHP维护一个XSLT处理器。

XSLT Script (另存为.xsl以便在下面的脚本中加载)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="idkey" match="combination" use="id_combination" />
  <xsl:template match="combinations">
    <xsl:copy>
      <xsl:apply-templates select="combination[generate-id() =
                                   generate-id(key('idkey',id_combination)[1])]"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="combination[generate-id() =
                       generate-id(key('idkey',id_combination)[1])]">
    <xsl:copy>
      <xsl:copy-of select="id_combination|quantity|unit_price_impact|reference"/>
      <combination_name>
        <xsl:for-each select="key('idkey',id_combination)">
          <xsl:value-of select="concat(group_name, ': ', attribute_name)" />
            <xsl:if test="position() != last()">
                <xsl:text> / </xsl:text>
            </xsl:if>               
        </xsl:for-each>
      </combination_name>
    </xsl:copy>
  </xsl:template>
</xsl:transform>
PHP

脚本

// LOAD XML AND XSL FILES
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('Input.xml');
$xslfile = new DOMDocument('1.0', 'UTF-8');
$xslfile->load('XSLTScript.xsl');
// TRANSFORM XML with XSLT
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslfile); 
$newXml = $proc->transformToXML($xml);
// ECHO OUTPUT STRING
echo $newXml;
$xml = new SimpleXMLElement($newXml);
$xpath = $xml->xpath('//combination');
$array = [];    
foreach($xpath as $result){
    $inner = [];
    foreach ($result as $node => $item) {        
        $inner[$node] = (string)$item;
    }
    $array[] = $inner;
}
var_dump($array);

转换后的XML

 <?xml version="1.0" encoding="UTF-8"?>
 <combinations>
   <combination>
     <id_combination>2289</id_combination>
     <quantity>4</quantity>
     <unit_price_impact>0.000000</unit_price_impact>
     <reference>K10100.1B</reference>
     <combination_name>Color: Blue / Size: 1</combination_name>
   </combination>
   <combination>
     <id_combination>2290</id_combination>
     <quantity>20</quantity>
     <unit_price_impact>0.000000</unit_price_impact>
     <reference>K10100.2B</reference>
     <combination_name>Color: Blue / Size: 2</combination_name>
   </combination>
 </combinations>

输出
 array(2) {
   [0]=>
   array(5) {
     ["id_combination"]=>
     string(4) "2289"
     ["quantity"]=>
     string(1) "4"
     ["unit_price_impact"]=>
     string(8) "0.000000"
     ["reference"]=>
     string(9) "K10100.1B"
     ["combination_name"]=>
     string(21) "Color: Blue / Size: 1"
   }
   [1]=>
   array(5) {
     ["id_combination"]=>
     string(4) "2290"
     ["quantity"]=>
      string(2) "20"
     ["unit_price_impact"]=>
     string(8) "0.000000"
     ["reference"]=>
    string(9) "K10100.2B"
     ["combination_name"]=>
     string(21) "Color: Blue / Size: 2"
   }
 }