添加空节点以始终成为相同数量的节点

时间:2013-08-01 13:00:50

标签: xslt add

  

嗨,我正在寻找一种方法来完成一个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>

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

如果您不想将样式表限制为始终使用4,则可以使用max()获取TopGroup个元素的最大数量。

当计数小于最大值时输出正确数量的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>

答案 2 :(得分: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>

<强>输出:

<?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>