2013-08-01 74 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>