如何使用XLST重命名父和子XML节点?

时间:2017-07-13 15:41:34

标签: xml xslt

我正在尝试将以下父/子注释重命名为XML文档中的几个级别

<product-lineitem>
    <price-adjustments>
        <price-adjustment>
           ...
        </price-adjustment>
        <price-adjustment>
           ...
        </price-adjustment>
    </price-adjustments>
</product-lineitem>

进入

<product-lineitem>
    <line-price-adjustments>
        <line-price-adjustment>
           ...
        </line-price-adjustment>
        <line-price-adjustment>
           ...
        </line-price-adjustment>
    </line-price-adjustments>
</product-lineitem>

我已经想出如何使用XSLT做到这一点,但我认为我复制了我的逻辑并且可能误用xslt,是否可以在少于以下两个模板中进行上述转换

<?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="product-lineitem/price-adjustments">
            <line-price-adjustments><xsl:apply-templates select="@*|node()" /></line-price-adjustments>
        </xsl:template>
        <xsl:template match="product-lineitem/price-adjustments/price-adjustment">
            <line-price-adjustment><xsl:apply-templates select="@*|node()" />    </line-price-adjustment>
    </xsl:template>
</xsl:transform>

我认为我正在创建xml-transform代码气味,因为我还在学习!

2 个答案:

答案 0 :(得分:3)

不,你没有创造出代码味道。您正在使用的模式,身份模板以及您希望更改的元素的覆盖模板通常是可行的方式。

您可以做的一个简化是,您实际上不需要指定要匹配的元素的完整路径。只需要元素名称

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

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

    <xsl:template match="price-adjustment">
        <line-price-adjustment>
            <xsl:apply-templates select="@*|node()" />
        </line-price-adjustment>
    </xsl:template>
</xsl:transform>

如果您在不同的元素名称下有price-adjustment,则只需要指定一个更全面的路径,例如,您不想更改。

如果您确定要匹配的元素永远不会有属性,那么您也可以用<xsl:apply-templates select="@*|node()" />替换<xsl:apply-templates />

答案 1 :(得分:2)

如果您只是想收紧代码,也可以使用以下模板。

    <xsl:template match="price-adjustment | price-adjustments">
        <xsl:element name="line-{name()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

......或:

    <xsl:template match="*[starts-with(name(), 'price-adjustment')]">
        <xsl:element name="line-{name()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

在您的示例输入XML的特定情况下,缩短像这样的代码并没有做太多。但是,如果你有很多元素,你想通过简单地添加或附加另一个字符串来以类似的方式重命名,这可以使你不必编写所有基本相同的模板。