使用XSLT将子节点移动到父属性中

时间:2009-05-18 01:12:08

标签: xml xslt

我有一些包含记录和子记录的XML,如下所示:

<data>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00">
        <record jsxid="id0x0b60ff10" string="101"/>
        <record jsxid="id0x0e64d8e8" string="63"/>
        <record jsxid="id0x2fd83f08" string="Y"/>
    </record>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00">
        <record jsxid="id0x0b60ff10" string="102"/>
        <record jsxid="id0x0e64d8e8" string="77"/>
        <record jsxid="id0x2fd83f08" string="Y"/>
    </record>       
<data>

我需要对其进行转换,以便将子记录的字符串属性作为连续编号的属性引入父记录,然后丢弃,如下所示:

<data>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="101" 2="63" 3="Y"/>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="102" 2="77" 3="Y"/>
<data>

子记录的数量在文档中是任意的,但在同一文档中保持静态。

有人会非常友好地指出XSLT解决方案吗?非常感谢。

2 个答案:

答案 0 :(得分:5)

这是一个完整的解决方案:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- By default, recursively copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But don't process any children of <record> (such as whitespace)... -->
  <xsl:template match="record/node()"/>

  <!-- ...except for doubly-nested records;
       convert them to attributes, named according to position -->
  <xsl:template match="record/record" priority="1">
    <xsl:variable name="pos">
      <xsl:number/>
    </xsl:variable>
    <xsl:attribute name="r{$pos}">
      <xsl:value-of select="@string"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

请注意,我将属性名称更改为“r1”,“r2”等,因为XML不允许您使用数字来启动名称。

答案 1 :(得分:1)

这可能会这样做,在处理顶级<record>元素时运行以下XSLT片段:

<xsl:for-each select="record">
    <xsl:attribute name="{position()}">
        <xsl:value-of select="@string" />
    </xsl:attribute>
</xsl:for-each>

本质上,这会迭代每个子{ - 1}}元素,并创建一个描述所需属性的<record>元素。调用<xsl:attribute>函数来获取顶级元素中的相对位置:1,2,3等。

这不是一个完整的解决方案;假设对XSLT有一定的了解。