如何使用PHP转换XML结构:simpleXMLElement

时间:2014-02-18 09:47:52

标签: php xml transform

我有以下xml:

<?xml version="1.0" encoding="UTF-8"?>

<product version="1.4" productId="{97550402-c98f-4b42-b7e7-521961e2700b}" groupId="ACER" codeId="NX.M81EX.080">
    <name>Notebook Acer Aspire XYZ</name>
    <vendor>Acer</vendor>
    <propertyGroup propertyGroupId="{3f2c48a7-b185-4fad-bd20-7d0c50502645}">
            <propertyGroupName>Product : Common</propertyGroupName>
            <property propertyId="2" type="Text" name="Part No.">
                    <value valueId="0">NX.M81EX.080</value>
            </property>
            <property propertyId="3" type="Text" name="Model No.">
                <value valueId="0">Acer XYZ</value>
            </property>
    </propertyGroup>
    <propertyGroup propertyGroupId="{869eec69-8f70-40ac-a41d-c8958d743ad3}">
            <propertyGroupName>Notebook</propertyGroupName>
            <property propertyId="2" type="Enum" name="CPU">
                    <value valueId="337">CPU XYZ</value>
            </property>
            <property propertyId="10" type="Enum" name="Graphics">
                    <value valueId="242">Graphics XYZ</value>
            </property>
            <property propertyId="5" type="Enum" name="RAM">
                    <value valueId="6">RAM XYZ</value>
            </property>
            <property propertyId="11" type="Enum" name="HDD">
                    <value valueId="34">HDD XYZ</value>
            </property>
    </propertyGroup>
    <file type="Datasheet" description="">http://www.site.com/xyz.pdf</file>
    <image type="other">http://www.site.com/abc.jpg</image>
    <image type="other">http://www.site.com/xyz.jpg</image>
</product>

我正在使用PHP:simpleXMLElement,并且必须将此XML构造成如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<feed>
    <products>
        <product>
            <codeId>NX.M81EX.080</codeId>
            <name>Notebook Acer Aspire XYZ</name>
            <vendor>Acer</vendor>
            <model>Acer XYZ</model>
            <category>Notebook</category>
            <CPU>CPU XYZ</CPU>
            <graphics>Graphics XYZ</graphics>
            <RAM>RAM XYZ</RAM>
            <HDD>HDD XYZ</HDD>
            <datasheet>http://www.site.com/xyz.pdf</datasheet>
            <image>http://www.site.com/xyz.jpg</image>
        </product>
    </products>
</feed>

我尝试了几个递归函数但没有成功。 我检索属性的值但无法检索属性名称。 你能帮助我吗。在此先感谢:)

1 个答案:

答案 0 :(得分:0)

您可以使用像这样的XSLT样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="name|vendor">
        <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="propertyGroup">
        <xsl:choose>
            <xsl:when test="propertyGroupName = 'Product : Common'">
                <xsl:apply-templates select="property" mode="common"/>
            </xsl:when>
            <xsl:otherwise>
                <category><xsl:value-of select="propertyGroupName"/></category>
                <xsl:apply-templates select="property"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="property" mode="common">
            <xsl:if test="@propertyId=2">
                <codeId><xsl:value-of select="."/></codeId>
            </xsl:if>
            <xsl:if test="@propertyId=1">
                <model><xsl:value-of select="."/></model>
            </xsl:if>
    </xsl:template>

    <xsl:template match="property">
        <xsl:element name="{@name}">
            <xsl:value-of select="value"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="file[@type='Datasheet']">
        <datasheet><xsl:value-of select="."/></datasheet>
    </xsl:template>

    <xsl:template match="image">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*|text()"/>
</xsl:stylesheet>

将上述数据转换为以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<feed>
   <products>
      <product>
         <name>Notebook Acer Aspire XYZ</name>
         <vendor>Acer</vendor>
         <codeId>NX.M81EX.080</codeId>
         <category>Notebook</category>
         <CPU>CPU XYZ</CPU>
         <Graphics>Graphics XYZ</Graphics>
         <RAM>RAM XYZ</RAM>
         <HDD>HDD XYZ</HDD>
         <datasheet>http://www.site.com/xyz.pdf</datasheet>
         <image>http://www.site.com/abc.jpg</image>
         <image>http://www.site.com/xyz.jpg</image>
      </product>
   </products>
</feed>

您可以加载XSL样式表,源XML并使用以下命令运行XSLT处理器:

$processor = new XsltProcessor();
$xsl = new DomDocument;
$xsl->load('stylesheet.xsl');
$processor->importStylesheet($xsl);

$source = new DomDocument;
$source->load('your-xml-file.xml');

$result = $processor->transformToXML($source));

如有必要,您可以编辑XSL并使其适用于更广泛的源文档。您的源有两个图像,因此结果产生了两个图像标记。如果您只想要最后一张图片,请将模板匹配更改为image[last()]