Xslt用于重命名列表

时间:2010-09-07 17:39:56

标签: xslt

我有这个XML:

<Root>
    <Tag>
        <Childlist>
            <I>1</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
        </Childlist>
        <Childlist>
            <I>11</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
        </Childlist>
    </Tag>
</Root>

我希望将其转换为:

<Root>
    <Tag>
        <Childlist>
            <item>
                <I>1</I>
                <Dlist>
                    <item>2</item>
                    <item>3</item>
                    <item>4</item>
                </Dlist>
            </item>
            <item>
                <I>11</I>
                <Dlist>
                    <item>2</item>
                    <item>3</item>
                    <item>4</item>
                </Dlist>
            </item>
        </Childlist>
    </Tag>
</Root>

使用XSLT。如您所见,第一个XML中的重复标记被替换为标记,列表标记被替换为父标记。

有人可以建议xslt进行此转换吗?

提前致谢。

修改:来自评论。

  

我遇到this xls的问题。   如果我在Dlist下面添加任何标签,它就会得到   附加到Dlist

     

还有其他的事情   和以下元素 [来自Dlist]

2 个答案:

答案 0 :(得分:1)

除了Dimitre的优秀答案,这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="Tag">
        <Tag>
            <Childlist>
                <xsl:apply-templates select="node()[1]"/>
            </Childlist>
        </Tag>
    </xsl:template>
    <xsl:template match="*/Dlist[1]">
        <xsl:copy>
            <xsl:call-template name="makeItem"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Childlist|Dlist" name="makeItem">
        <Item>
            <xsl:apply-templates select="node()[1]"/>
        </Item>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<Root>
    <Tag>
        <Childlist>
            <Item>
                <I>1</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
            </Item>
            <Item>
                <I>11</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
            </Item>
        </Childlist>
    </Tag>
</Root>

修改:使用此输入:

<Root>
    <Tag>
        <Childlist>
            <I>1</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
            <F>1</F>
        </Childlist>
        <Childlist>
            <I>11</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
            <F>11</F>
        </Childlist>
    </Tag>
</Root>

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="Tag">
        <Tag>
            <Childlist>
                <xsl:apply-templates select="node()[1]"/>
            </Childlist>
        </Tag>
    </xsl:template>
    <xsl:template match="*/Dlist[last()]" name="makeItem">
        <Item>
            <xsl:apply-templates select="node()[1]"/>
        </Item>
    </xsl:template>
    <xsl:template match="*/Dlist[1]">
        <xsl:copy>
            <xsl:call-template name="wrap"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()
                                         [not(self::Dlist)][1]"/>
    </xsl:template>
    <xsl:template match="Childlist|Dlist" name="wrap">
        <xsl:call-template name="makeItem"/>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<Root>
    <Tag>
        <Childlist>
            <Item>
                <I>1</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
                <F>1</F>
            </Item>
            <Item>
                <I>11</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
                <F>11</F>
            </Item>
        </Childlist>
    </Tag>
</Root>

注意:这假定Dlist个元素都是下一个兄弟姐妹。因此,Dlist[1]会打开新级别,然后将模板应用于下一个没有Dlist节点,Dlist[last()]关闭不将模板应用于下一个兄弟级别的级别。

答案 1 :(得分:0)

此转化

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kDlist" match="Dlist"
 use="generate-id((.|preceding-sibling::Dlist)[1])"/>

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

 <xsl:template match="*[Childlist]">
  <xsl:copy>
   <xsl:copy-of select="@*"/>
   <Childlist>
    <xsl:apply-templates/>
   </Childlist>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="Childlist|Dlist" name="makeItem">
  <Item>
   <xsl:apply-templates/>
  </Item>
 </xsl:template>

 <xsl:template match="Dlist[not(preceding-sibling::Dlist)]">
  <Dlist>
   <xsl:apply-templates select="key('kDlist', generate-id())" mode="copy"/>
  </Dlist>
 </xsl:template>

 <xsl:template match="Dlist" mode="copy">
  <xsl:call-template name="makeItem"/>
 </xsl:template>

 <xsl:template match="Dlist"/>
</xsl:stylesheet>

应用于此XML文档时(原始文本已更正为格式良好):

<Root>
    <Tag>
        <Childlist>
            <I>1</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
        </Childlist>
        <Childlist>
            <I>11</I>
            <Dlist>2</Dlist>
            <Dlist>3</Dlist>
            <Dlist>4</Dlist>
        </Childlist>
    </Tag>
</Root>

生成想要的正确结果

<Root>
    <Tag>
        <Childlist>
            <Item>
                <I>1</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
            </Item>
            <Item>
                <I>11</I>
                <Dlist>
                    <Item>2</Item>
                    <Item>3</Item>
                    <Item>4</Item>
                </Dlist>
            </Item>
        </Childlist>
    </Tag>
</Root>