【问题标题】:How to transform XML structure with PHP: simpleXMLElement如何使用 PHP 转换 XML 结构:simpleXMLElement
【发布时间】:2014-02-18 09:47:52
【问题描述】:

我有以下 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>

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

【问题讨论】:

    标签: php xml transform


    【解决方案1】:

    您可以使用这样的 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()]

    【讨论】:

      猜你喜欢
      • 2013-07-13
      • 2012-05-31
      • 1970-01-01
      • 2015-08-04
      • 2011-04-30
      • 1970-01-01
      • 2016-12-14
      • 1970-01-01
      • 2013-02-11
      相关资源
      最近更新 更多