移动和重命名 XML 节点的内容

Moving and renaming contents of an XML node

我是 XSLT 翻译方面的新手,搜索这个问题已经有一段时间了,但没有找到任何答案。我有一个 XML 文件,如下所示:

<item>
  <code>I001</code>
  <description>DEF</description>
  <properties>
    <line1>
      <key>key 1</key>
      <value>value 1</value>
    </line1>
    <line2>
      <key>key 2</key>
      <value>value 2</value>
    </line2>
  </properties>
</item>

我需要用来处理这些数据的标签软件无法处理这种水平的 xml,所以我必须将它转换成这样的东西

<?xml version="1.0" encoding="utf-8"?>
<item>
  <code>I001</code>
  <description>DEF</description>
  <P1_key>key 1</P1_key>
  <P1_value>value 1</P1_value>
  <P2_key>key 1</P2_key>
  <P2_value>value</P2_value>
</item>

到目前为止,我已经想出了一个看起来像这样的 xsl 文件:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

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

  <!-- special rules ... -->
  <xsl:template match="properties/line1/*">
    <xsl:element name="P1_{local-name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="properties/line2/*">
    <xsl:element name="P2_{local-name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

这只是我需要的一部分(重命名元素),结果如下所示:

<?xml version="1.0" encoding="utf-8"?>
<item>
  <code>I001</code>
  <description>DEF</description>
  <properties>
    <line1>
      <P1_key>key 1</P1_key>
      <P1_value>value 1</P1_value>
    </line1>
    <line2>
      <P2_key>key 1</P2_key>
      <P2_value>value</P2_value>
    </line2>
  </properties>
</item>

我现在想知道的是如何将重命名后的元素(P1_key、P1_value、P2_key、P2_value)移动到level

如有任何提示,我们将不胜感激。

谢谢

怎么样:

XSLT 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="/item">
    <xsl:copy>
        <xsl:copy-of select="code | description"/>
        <xsl:for-each select="properties/*/key">
            <xsl:element name="P{position()}_key">
                <xsl:value-of select="."/>
            </xsl:element>
            <xsl:element name="P{position()}_value">
                <xsl:value-of select="following-sibling::value[1]"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:copy>
</xsl:template> 

</xsl:stylesheet>

或者也许:

<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="/item">
    <xsl:copy>
        <xsl:copy-of select="code | description"/>
        <xsl:for-each select="properties/*/key">
        <xsl:variable name="line-num" select="substring-after(name(..), 'line')" />
            <xsl:element name="P{$line-num}_key">
                <xsl:value-of select="."/>
            </xsl:element>
            <xsl:element name="P{$line-num}_value">
                <xsl:value-of select="following-sibling::value[1]"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:copy>
</xsl:template> 

</xsl:stylesheet>

当然,如果总是恰好有两行,你可以拼写出来:

<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="/item">
    <xsl:copy>
        <xsl:copy-of select="code | description"/>
        <P1_key>
            <xsl:value-of select="properties/line1/key" />
        </P1_key>
        <P1_value>
            <xsl:value-of select="properties/line1/value" />
        </P1_value>
        <P2_key>
            <xsl:value-of select="properties/line2/key" />
        </P2_key>
        <P2_value>
            <xsl:value-of select="properties/line2/value" />
        </P2_value>
    </xsl:copy>
</xsl:template> 

</xsl:stylesheet>

顺便说一句,如果您添加另一个模板,您的方法也可以工作:

<xsl:template match="properties | line1 | line2">
    <xsl:apply-templates />
</xsl:template>