2012-07-20 177 views
0

计数的节点,我需要输出的附属建筑节点(仅且只有有一个“vacant'孩子的那些)与正确的序列号(见XML)XSLT 1.0:在XSLT

有以下XML没有属性,只是元素和价值观。

<stuff> 
    <locations> 
     <location> 
      <properties> 
       <property> 
        <belongings> 
         <house> 
          <houseWithAC/> 
         </house> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <outbuilding/> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <outbuilding> 
          <vacant/> 
         </outbuilding> 
        </belongings> 
       </property> 
       <property>    
        <belongings> 
         <outbuilding> 
          <vacant/> 
         </outbuilding> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <vehicle/> 
        </belongings> 
       </property> 
      </properties> 
     </location> 
     <location> 
      <properties> 
       <property> 
        <belongings> 
         <vehicle/> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <outbuilding/> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <house/> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <outbuilding> 
          <vacant/> 
         </outbuilding> 
        </belongings> 
       </property> 
       <property> 
        <belongings> 
         <barn/> 
        </belongings> 
       </property> 
      </properties> 
      </location> 
     </locations> 
</stuff> 
  1. 测序:我需要计算每个位置属于每个子节点(为前房屋,附属建筑,汽车)注意,房子houseWithAC孩子算作两个节点! 序列格式是禄###/###项目

  2. 我需要输出有空置的孩子每外屋节点,用正确的序列号(见上文)

还要注意:“收藏”节点,如地点,属性有许多孩子,而节点所有物 - 只有一个。

我试图创建一个递归循环,但ID不工作:如果我有附属建筑节点,而“空置”柴尔德我还是踏进if语句(看起来像条件​​为真永诺)

东西像这样: 。 。 。 。 。 。 。 。 。 。 。

<xsl:for-each select="Locations/Location"> 
    <xsl:variable name="LOCID"> 
     <xsl:number level="single" count="*" format="001"/> 
    </xsl:variable> 
    <xsl:call-template name="WriteItems"> 
     <xsl:with-param name="propertiesNodes" select="properties/property"/> 
     <xsl:with-param name="NumberOfProperties" select="count(properties/property)"/> 
     <xsl:with-param name="LocCount" select="$LOCID"/> 
    </xsl:call-template> 
</xsl:for-each>  
. . . . . . . . . . . . . 


<xsl:template name="WriteItems"> 
    <xsl:param name="propertiesNodes"/> 
    <xsl:param name="NumberOfProperties"/> 
    <xsl:param name="LocCount"/> 
    <xsl:param name="Index">1</xsl:param> 
    <xsl:param name="ItemCount">1</xsl:param>  
    <xsl:choose> 
     <xsl:when test="$Index > $NumberOfProperties"/> 
     <xsl:otherwise> 
      <xsl:choose> 
       <xsl:when test="$propertiesNodes[$Index]/belongings/house/houseWithAC"> 
        <xsl:call-template name="WriteItems"> 
         <xsl:with-param name="propertiesNodes" select="$propertiesNodes"/> 
         <xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/> 
         <xsl:with-param name="LocCount" select="$LocCount"/> 
         <xsl:with-param name="Index" select="$Index + 1"/> 
         <xsl:with-param name="ItemCount" select="$ItemCount + 2"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:when test="$propertiesNodes[$Index]/belongings/house"> 
        <xsl:call-template name="WriteItems"> 
         <xsl:with-param name="propertiesNodes" select="$propertiesNodes"/> 
         <xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/> 
         <xsl:with-param name="LocCount" select="$LocCount"/> 
         <xsl:with-param name="Index" select="$Index + 1"/> 
         <xsl:with-param name="ItemCount" select="$ItemCount + 1"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:when test="$propertiesNodes[$Index]/belongings/vehicle"> 
        <xsl:call-template name="WriteItems"> 
         <xsl:with-param name="propertiesNodes" select="$propertiesNodes"/> 
         <xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/> 
         <xsl:with-param name="LocCount" select="$LocCount"/> 
         <xsl:with-param name="Index" select="$Index + 1"/> 
         <xsl:with-param name="ItemCount" select="$ItemCount + 1"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:when test="$propertiesNodes[$Index]/belongings/barn"> 
        <xsl:call-template name="WriteItems"> 
         <xsl:with-param name="propertiesNodes" select="$propertiesNodes"/> 
         <xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/> 
         <xsl:with-param name="LocCount" select="$LocCount"/> 
         <xsl:with-param name="Index" select="$Index + 1"/> 
         <xsl:with-param name="ItemCount" select="$ItemCount + 1"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:when test="$propertiesNodes[$Index]/belongings/outbuilding"> 
        <xsl:if test="$propertiesNodes[$Index]/belongings/outbuilding/vacant"> 
         <xsl:variable name="ITEMID"> 
          <xsl:value-of select="format-number($ItemCount,'000')"/> 
         </xsl:variable> 

         .... output as concat('- ', $LocCount, '/', $ITEMID) ...... some description .... 


        </xsl:if> 
        <xsl:call-template name="WriteItems"> 
         <xsl:with-param name="propertiesNodes" select="$propertiesNodes"/> 
         <xsl:with-param name="NumberOfProperties" select="$NumberOfProperties"/> 
         <xsl:with-param name="LocCount" select="$LocCount"/> 
         <xsl:with-param name="Index" select="$Index + 1"/> 
         <xsl:with-param name="ItemCount" select="$ItemCount + 1"/> 
        </xsl:call-template> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
+0

这是非常混乱和不精确的。没有像“收集节点”这样的术语,并且不可能猜测你的意思。如果你提供确切的想要的结果,人们可能会更好地猜测实际需要的东西。 – 2012-07-20 14:27:13

+0

您可以显示(1)您的示例输入所需的输出XML; (2)你得到的实际输出XML会很有帮助。 – LarsH 2012-07-20 14:28:07

+0

我用双引号:“集合”节点。这些是具有多个同类儿童的节点。 – user1540823 2012-07-20 14:31:58

回答

2

我不知道我是否正确理解你的问题,但如果这是你想要什么:

对于每个空缺的“项目”,输出:

  1. 含有的位置所有位置内的位置,和
  2. 所有的“项目”内的“项目”的位置在含位置

然后,您可以通过遍历位置和“项目”并使用position()函数在发现匹配时指示位置来实现此目的。就像这样:

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

    <xsl:template match="/"> 
    <xsl:for-each select="//location"> 
     <xsl:variable name="locposition" select="position()"/> 
     <xsl:for-each select=".//belongings//*[not(self::vacant)]"> 
     <xsl:if test="vacant"> 
      <xsl:value-of select="format-number($locposition, '000')"/> 
      <xsl:text>/</xsl:text> 
      <xsl:value-of select="format-number(position(), '000')"/> 
      <xsl:text>&#xa;</xsl:text> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

你的榜样输入,这将输出如下:

001/004 
001/005 
002/004 

编辑补充:下面是使用xsl:number从而避免了明确的循环的替代解决方案:

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

    <xsl:template match="*[vacant]"> 
    <xsl:number count="location" format="001"/> 
    <xsl:text>/</xsl:text> 
    <xsl:number count="*[not(self::vacant)][ancestor::belongings]" 
       level="any" from="location" format="001"/> 
    <xsl:text>&#xa;</xsl:text> 
    </xsl:template> 

    <xsl:template match="text()"/> 

</xsl:stylesheet>