【问题标题】:How to use rename both Parent and Child XML Nodes Using XLST?如何使用 XSLT 重命名父和子 XML 节点?
【发布时间】:2017-07-13 15:41:34
【问题描述】:

我正在尝试重命名以下位于 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 转换代码的味道,因为我还在学习!

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    不,您不是在制造代码气味。您正在使用的模式、身份模板以及您希望更改的元素的覆盖模板,通常是要走的路。

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

    <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 在不同的元素名称下,您只需要指定更完整的路径,例如,您不想更改。

    如果您确定要匹配的元素永远不会包含属性,您也可以将 &lt;xsl:apply-templates select="@*|node()" /&gt; 替换为 &lt;xsl:apply-templates /&gt;

    【讨论】:

      【解决方案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 的特定情况下,像这样缩短代码并没有多大作用。但是,如果您想通过简单地预先或附加另一个字符串来以类似的方式重命名许多元素,这可以使您不必编写大量模板,这些模板基本上都做同样的事情。

      【讨论】:

      • &lt;xsl:element name="{concat('line-', name())}"&gt; 可以简化为&lt;xsl:element name="line-{name()}"&gt;
      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 2020-01-24
      相关资源
      最近更新 更多