使用XSLT转换XML - 根节点不存在

时间:2016-06-11 10:09:05

标签: xml xslt transformation

我有一个XML文件:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<File>
    <Customer>
        <LastName>MyLastName</LastName>
    </Customer>
    <Cars>
        <Car>
            <Color>Blue</Color>
            <Model>Car2</Model>
            <Year>1988</Year>
            <Speed>250</Speed>
        </Car>
        <Car>
            <Color>Green</Color>
            <Model>Car3</Model>
            <Year>1989</Year>
            <Speed>350</Speed>
        </Car>
    </Cars>
</File>

我想使用XSLT对其进行转换:

<?xml version="1.0" encoding="utf-8"?>
<File>
    <Purchaser>
        <Name>MyLastName</Name>
    </Purchaser>
    <vehicles>
        <vehicle>
            <vehicleColor>Blue</vehicleColor>
            <vehicleModel>Car2</vehicleModel>
            <vehicleYear>1988</vehicleYear>
            <vehicleSpeed>250</vehicleSpeed>
        </vehicle>
        <vehicle>
            <vehicleColor>Green</vehicleColor>
            <vehicleModel>Car3</vehicleModel>
            <vehicleYear>1989</vehicleYear>
            <vehicleSpeed>350</vehicleSpeed>
        </vehicle>
    </vehicles>
</File>

我的XSLT文件:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"
            indent="yes"
            encoding="utf-8"
            media-type="text/xml"/>


    <xsl:template match="File/Customer">
        <xsl:element name="Purchaser">
            <xsl:element name="Name">
                <xsl:value-of select="LastName"/>
            </xsl:element>
        </xsl:element>
    </xsl:template> 

    <xsl:template match="File/Cars">
        <xsl:element name="vehicles">
            <xsl:for-each select="Car">
                <xsl:element name="vehicle">
                    <xsl:element name="vehicleColor">
                        <xsl:value-of select="Color"/>
                    </xsl:element>
                    <xsl:element name="vehicleModel">
                        <xsl:value-of select="Model"/>
                    </xsl:element>
                    <xsl:element name="vehicleYear">
                        <xsl:value-of select="Year"/>
                    </xsl:element>
                    <xsl:element name="vehicleSpeed">
                        <xsl:value-of select="Speed"/>
                    </xsl:element>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

但我的输出文件中没有根节点。怎么做?

此外,这是进行转型的好方法吗?有几个模板堆叠?

2 个答案:

答案 0 :(得分:2)

我建议从身份转换模板开始

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

复制您不想像File元素那样进行转换的节点,然后允许您添加执行转换的模板,例如

<xsl:template match="Customer">
  <Purchaser>
    <xsl:apply-templates/>
  </Purchaser>
</xsl:template>

<xsl:template match="LastName">
  <Name>
    <xsl:apply-templates/>
  </Name>
</xsl:template>

<xsl:template match="Cars">
  <vehicles>
    <xsl:apply-templates/>
  </vehicles>
</xsl:template>

<xsl:template match="Car">
  <vehicle>
    <xsl:apply-templates/>
  </vehicle>
</xsl:template>

<xsl:template match="Car/*">
  <xsl:element name="vehicle{local-name()}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

等等。如您所见,我只是在大多数地方使用了文字结果元素而不是更详细的xsl:element,因为只有在运行时需要计算名称和/或命名空间时才需要它。

答案 1 :(得分:0)

  

这是进行转型的好方法吗?有几个模板   堆叠?

您可以使用多个模板或一个模板 - 在这种情况下,这两种方法都没有明显的优势或劣势。就个人而言,我会简短而简单地坚持一个模板(主要是因为你只复制了一个节点而没有修改):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/File">
    <File>
        <Purchaser>
            <Name>
                <xsl:value-of select="Customer/LastName"/>
            </Name>
        </Purchaser>
        <vehicles>
            <xsl:for-each select="Cars/Car">
                <vehicle>
                    <xsl:for-each select="*">
                        <xsl:element name="vehicle{name()}">
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                </vehicle>
            </xsl:for-each>
        </vehicles>
    </File>
</xsl:template>

</xsl:stylesheet>
相关问题