xslt - 添加父元素并重命名子元素

标签 xslt xslt-1.0 xslt-2.0

我正在尝试在导入和导出下循环子元素。创建一个父元素fields,并将名称为field的所有元素放入其中,只是在导入下,不包括结构下的元素字段,在所有元素结构上创建元素结构,最后的工作是重命名所有具有值的元素的属性名称。我只知道先复制所有这些,无法进入下一步来创建正确的模板。

输入:

<?xml version='1.0'?>
<jco name="TEST" timestamp="1275691115508" version="1.0">
<import>
    <field name="RESERVED_IN">12345</field>
    <structure name="GM_HEADER">
                <field name="PSTNG_DATE">2004-07-02</field>
        <field name="DOC_DATE">2004-04-02</field>
    </structure>
    <structure name="TESTRUN">
        <field name="TESTRUN"></field>
    </structure>
</import>
<export>
    <field name="RESERVED_OUT"></field>
    <structure name="GM_HEADER_RET">
        <field name="MAT_DOC"></field>
        <field name="DOC_YEAR">0000</field>
    </structure>
</export>
</jco>

期望的输出:

<?xml version="1.0" ?>
<jco version="1.0" name="TEST">
    <import>
        <fields>
            <RESERVED_IN>12345</RESERVED_IN>
        </fields>
        <structures>
            <GM_HEADER>
                <PSTNG_DATE>2004-07-02</PSTNG_DATE>
                <DOC_DATE>2004-04-02</DOC_DATE>
            </GM_HEADER>
            <TESTRUN>
                <TESTRUN></TESTRUN>
            </TESTRUN>
        </structures>
   </import>
   <export>
       <fields>
           <RESERVED_OUT></RESERVED_OUT>
       </fields>
       <structures>
           <GM_HEADER_RET>
               <MAT_DOC></MAT_DOC>
               <DOC_YEAR>0000</DOC_YEAR>
           </GM_HEADER_RET>
       </structures>
   </export>
</jco>

下面是我的 xslt,但看起来很困惑。

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

        <xsl:template match="import">
            <fields>
                <xsl:for-each select="/field">
                    <xsl:call-template name="field" />
                </xsl:for-each>
            </fields>
            <structures>
                <xsl:for-each select="/structure">
                    <xsl:element name="{@name}">
                        <xsl:value-of select="." />
                    </xsl:element>
                    <xsl:call-template name="field" />
                </xsl:for-each>
            </structures>
        </xsl:template>

        <xsl:template name="field">
            <xsl:for-each select="/field">
                    <xsl:element name="{@name}">
                        <xsl:value-of select="." />
                    </xsl:element>
                </xsl:for-each>
        </xsl:template>

最佳答案

使用模板和apply-templates,而不是for-each,而且效果相当优雅:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs">

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

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

<xsl:template match="import | export">
  <xsl:copy>
    <fields>
      <xsl:apply-templates select="field"/>
    </fields>
    <structures>
      <xsl:apply-templates select="structure"/>
    </structures>
  </xsl:copy>
</xsl:template>

<xsl:template match="field | structure">
  <xsl:element name="{@name}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

关于xslt - 添加父元素并重命名子元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15696320/

相关文章:

c# - 是否可以在 XSL 中展平 XML 层次结构?

XSLT:有效测试 'cousin' 节点是否存在

xslt - XSL 子字符串 - 最后一次出现字符串之后

xslt - xslt中多次出现相同的路径

xslt - 转换合并*.xml

string - 查找 xslt 中字符串中子字符串的出现次数

java - 使用 java 对输入 XML 进行 XSL 转换

xml - 用于多个字符串的 XPath/XSLT contains()

xml - xslt 向 xml 根节点添加属性

position - 在 xpath 表达式中引用当前节点的位置