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

时间:2015-03-04 20:32:22

标签: xslt transformation

我是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)移动到该级别。

任何提示都将不胜感激。

由于

1 个答案:

答案 0 :(得分:1)

怎么样:

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>