2012-06-03 77 views
3

我正在寻找基于元素数目变换节点。即5,然后关闭节点并重新打开一个新节点。 见下面的例子使用XSLT根据节点数来变换XML

<root> 
    <branch> 
    <foo>bar</foo> 
    <foo>bar2</foo> 
    <foo>bar3</foo> 
    <foo>bar4</foo> 
    <foo>bar5</foo> 
    <foo>bar6</foo> 
    <foo>bar7</foo> 
    </branch> 
<root> 

应该成为

<root> 
    <branch> 
    <foo>bar</foo> 
    <foo>bar2</foo> 
    <foo>bar3</foo> 
    <foo>bar4</foo> 
    <foo>bar5</foo> 
    <branch> 
    </branch> 
    <foo>bar6</foo> 
    <foo>bar7</foo> 
    </branch> 
<root> 

这是如何在XSLT来完成请帮助。

回答

4

I.这XSLT 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:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <root> 
    <xsl:apply-templates/> 
    </root> 
</xsl:template> 

<xsl:template match="foo[position() mod 5 = 1]"> 
    <branch> 
    <xsl:copy-of select= 
    ". | following-sibling::*[not(position() > 4)]"/> 
    </branch> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

当所提供的XML文档应用(校正为良好的形成):

<root> 
    <branch> 
     <foo>bar</foo> 
     <foo>bar2</foo> 
     <foo>bar3</foo> 
     <foo>bar4</foo> 
     <foo>bar5</foo> 
     <foo>bar6</foo> 
     <foo>bar7</foo> 
    </branch> 
</root> 

产生想要的,正确结果:

<root> 
    <branch> 
     <foo>bar</foo> 
     <foo>bar2</foo> 
     <foo>bar3</foo> 
     <foo>bar4</foo> 
     <foo>bar5</foo> 
    </branch> 
    <branch> 
     <foo>bar6</foo> 
     <foo>bar7</foo> 
    </branch> 
</root> 

说明

这是“位置分组”,其中一组的每个起动元件是所述第一5元组(因此其位置满足的情况下:position() mod 5 = 1


二, XSLT 2.0解决方案

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

<xsl:template match="/*"> 
    <root> 
    <xsl:for-each-group select="*/*" 
     group-adjacent="(position() -1) idiv 5"> 
      <branch> 
      <xsl:sequence select="current-group()"/> 
      </branch> 
    </xsl:for-each-group> 
    </root> 
</xsl:template> 
</xsl:stylesheet> 

当该XSLT 2.0变换对相同的XML文档(以上)应用中,相同的想要的,正确的结果产生

说明

正确使用与group-adjacent属性和current-group()功能<xsl:for-each-group> XSLT 2.0指令。

0

在XSLT中没有像“打开”或“关闭”节点那样的操作。你对加工模型有了一个错误的想法,直到你把它放在脑海中,你将很难解决这类问题。尤其是,您还没有理解XSLT是(概念上)创建结果树,而不是包含带有开始和结束标记的词法XML的文件。您需要做的是在结果树中创建与源树中每个五个节点组相对应的一个节点(或者等价地,在结果树中创建一个节点,以对应源树中每个节点的位置为多个5)。

Dimitre的解决方案是完全正确的,但我个人认为给你一个工作解决方案而不解释你思考错误的地方并不是解决问题的最佳方法。