2013-08-01 37 views
1

嗨,我正在寻找一种方式,以成为元素的固定次数来完成的XML。在这种情况下,我们希望元素“Top”的数量总是4.添加的元素应该是空的。 这是例如输入XML:加空节点始终成为相同数量的节点

<Root> 
<Group> 
<Top> 
    <x>test1</x> 
    <y>test2</y> 
</Top> 
<Top> 
    <x>test8</x> 
    <y>test23</y> 
</Top> 
<Top> 
    <x>test22</x> 
    <y>test2</y> 
</Top> 
<Top> 
    <x>test52</x> 
    <y>test27</y> 
</Top> 
</Group> 
<Group> 
<Top> 
    <x>test18</x> 
    <y>test39</y> 
</Top> 
</Group> 
<Group> 
<Top> 
    <x>test68</x> 
    <y>test99</y> 
</Top> 
<Top> 
    <x>test88</x> 
    <y>test100</y> 
</Top> 
</Group> 
</Root> 

的希望输出应该是:

<Root> 
<Group> 
<Top> 
    <x>test1</x> 
    <y>test2</y> 
</Top> 
<Top> 
    <x>test8</x> 
    <y>test23</y> 
</Top> 
<Top> 
    <x>test22</x> 
    <y>test2</y> 
</Top> 
<Top> 
    <x>test52</x> 
    <y>test27</y> 
</Top> 
</Group> 
<Group> 
<Top> 
    <x>test18</x> 
    <y>test39</y> 
</Top> 
<Top> 
    <x></x> 
    <y></y> 
</Top> 
<Top> 
    <x></x> 
    <y></y> 
</Top> 
<Top> 
    <x></x> 
    <y></y> 
</Top> 
</Group> 
<Group> 
<Top> 
    <x>test68</x> 
    <y>test99</y> 
</Top> 
<Top> 
    <x>test88</x> 
    <y>test100</y> 
</Top> 
<Top> 
    <x></x> 
    <y></y> 
</Top> 
<Top> 
    <x></x> 
    <y></y> 
</Top> 
</Group> 
</Root> 

回答

0

这个怎么样:

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

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

    <xsl:template match="Group"> 
    <xsl:copy> 
     <xsl:apply-templates select="Top" /> 
     <xsl:call-template name="AddTops"> 
     <xsl:with-param name="count" select="4 - count(Top)" /> 
     </xsl:call-template> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template name="AddTops"> 
    <xsl:param name="count" /> 

    <xsl:if test="$count > 0"> 
     <Top> 
     <x /> 
     <y /> 
     </Top> 

     <xsl:call-template name="AddTops"> 
     <xsl:with-param name="count" select="$count - 1" /> 
     </xsl:call-template> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

当你的样品输入运行,结果是:

<Root> 
    <Group> 
    <Top> 
     <x>test1</x> 
     <y>test2</y> 
    </Top> 
    <Top> 
     <x>test8</x> 
     <y>test23</y> 
    </Top> 
    <Top> 
     <x>test22</x> 
     <y>test2</y> 
    </Top> 
    <Top> 
     <x>test52</x> 
     <y>test27</y> 
    </Top> 
    </Group> 
    <Group> 
    <Top> 
     <x>test18</x> 
     <y>test39</y> 
    </Top> 
    <Top> 
     <x /> 
     <y /> 
    </Top> 
    <Top> 
     <x /> 
     <y /> 
    </Top> 
    <Top> 
     <x /> 
     <y /> 
    </Top> 
    </Group> 
    <Group> 
    <Top> 
     <x>test68</x> 
     <y>test99</y> 
    </Top> 
    <Top> 
     <x>test88</x> 
     <y>test100</y> 
    </Top> 
    <Top> 
     <x /> 
     <y /> 
    </Top> 
    <Top> 
     <x /> 
     <y /> 
    </Top> 
    </Group> 
</Root> 
+0

您好JLRishe,坦克。测试需要一些时间,因为我的生产文件有点复杂。但现在所有的作品都是它应该的! –

0

如果你不希望限制样式表总是使用4,你可以使用max()获得Top元素的最大计数的Group

然后输出正确的数,当计数小于最大Top元件。

你可以用XSLT 1.0递归模板输出,但因为你没有指定版本,并没有提供一个例子,我会给你一个答案2.0 ...

XML输入

<Root> 
    <Group> 
     <Top> 
      <x>test1</x> 
      <y>test2</y> 
     </Top> 
     <Top> 
      <x>test8</x> 
      <y>test23</y> 
     </Top> 
     <Top> 
      <x>test22</x> 
      <y>test2</y> 
     </Top> 
     <Top> 
      <x>test52</x> 
      <y>test27</y> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
      <x>test18</x> 
      <y>test39</y> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
      <x>test68</x> 
      <y>test99</y> 
     </Top> 
     <Top> 
      <x>test88</x> 
      <y>test100</y> 
     </Top> 
    </Group> 
</Root> 

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="tops" select="max(/*/Group/count(Top))"/> 

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

    <xsl:template match="Group"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
      <xsl:for-each select="1 to $tops - count(Top)"> 
       <Top> 
        <x/> 
        <y/> 
       </Top> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML输出

<Root> 
    <Group> 
     <Top> 
     <x>test1</x> 
     <y>test2</y> 
     </Top> 
     <Top> 
     <x>test8</x> 
     <y>test23</y> 
     </Top> 
     <Top> 
     <x>test22</x> 
     <y>test2</y> 
     </Top> 
     <Top> 
     <x>test52</x> 
     <y>test27</y> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
     <x>test18</x> 
     <y>test39</y> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
     <x>test68</x> 
     <y>test99</y> 
     </Top> 
     <Top> 
     <x>test88</x> 
     <y>test100</y> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
    </Group> 
</Root> 
0

的1.0实施例是:

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

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:param name="TopRequired" select="4"/> 

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

    <xsl:template match="Group"> 
    <xsl:variable name="CountTop" select="count(Top)"/> 
    <xsl:choose> 
     <xsl:when test="$CountTop = number($TopRequired)"> 
     <Group> 
      <xsl:copy-of select="Top"/> 
     </Group> 
     </xsl:when> 
     <xsl:otherwise> 
     <Group> 
      <xsl:copy-of select="Top"/> 
      <xsl:call-template name="createDummyTop"> 
      <xsl:with-param name="RequiredTop" select="number($TopRequired) - $CountTop"/> 
      </xsl:call-template> 
     </Group> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template name="createDummyTop"> 
    <xsl:param name="RequiredTop"/> 
    <xsl:if test="$RequiredTop != 0"> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <xsl:call-template name="createDummyTop"> 
     <xsl:with-param name="RequiredTop" select="$RequiredTop - 1"/> 
     </xsl:call-template> 
    </xsl:if> 

    </xsl:template> 

</xsl:stylesheet> 

OUTPUT:用于溶液

<?xml version="1.0" encoding="utf-8"?> 
<Root> 
    <Group> 
     <Top> 
     <x>test1</x> 
     <y>test2</y> 
     </Top> 
     <Top> 
     <x>test8</x> 
     <y>test23</y> 
     </Top> 
     <Top> 
     <x>test22</x> 
     <y>test2</y> 
     </Top> 
     <Top> 
     <x>test52</x> 
     <y>test27</y> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
     <x>test18</x> 
     <y>test39</y> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
    </Group> 
    <Group> 
     <Top> 
     <x>test68</x> 
     <y>test99</y> 
     </Top> 
     <Top> 
     <x>test88</x> 
     <y>test100</y> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
     <Top> 
     <x/> 
     <y/> 
     </Top> 
    </Group> 
</Root>