XSLT1.0:计算XSLT中的节点数

XSLT1.0:计算XSLT中的节点数,xslt,xslt-1.0,Xslt,Xslt 1.0,我需要输出具有正确序列号的外部节点(仅和只有具有“空”子节点的节点)(请参见XML) 下面的XML中没有属性,只有元素和值 <stuff> <locations> <location> <properties> <property> <belongings>

我需要输出具有正确序列号的外部节点(仅和只有具有“空”子节点的节点)(请参见XML)

下面的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>

  • 排序:我需要计算每个位置(例如房屋、外屋、车辆)的每个属于的子节点。注意,有houseithac子节点的房屋计算为两个节点 序列格式为Loc####/Item###

  • 我需要输出每个有空子节点的外屋节点,以及正确的序列号(见上文)

  • 还请注意:“集合”节点如位置、属性有许多子节点,而节点属性只有一个子节点

    我试图创建一个递归循环,但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>
    
    
    . . . . . . . . . . . . .
    1.
    1.
    .... 输出为concat(“-”、$LocCount、“/”、$ITEMID)。。。。。。一些描述。。。。
    
    我不确定是否正确理解了您的问题,但如果这是您想要的:

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

  • 包含位置在所有位置中的位置,以及
  • “项目”在包含位置的所有“项目”中的位置
  • 然后,您可以通过在位置和“项目”上循环,并使用函数在找到匹配项时告知位置来实现这一点。像这样:

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

    编辑添加:这里有一个替代解决方案,使用它可以避免显式循环:

    <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>
    
    
    / 
    
    ;
    
    这是非常混乱和不准确的。这里没有“集合节点”这样的术语,因此不可能猜出您的意思。如果您提供了所需的确切结果,人们可能会更好地猜测实际需要的内容;(2)您得到的实际输出XML会很有帮助。我使用了双引号:“collection”节点。这些节点具有多个相同类型的子节点。所需的输出将不是XML格式,而是pdf格式。我只是想更好地理解这个逻辑。输出应该有:001/004。。。某物001 / 005 ... 某物002 / 004 ... 如果不是XML,输出是什么?文本?“最终以pdf格式”其实并不重要……重要的是您正在使用的样式表的当前输出,以及它与您期望的输出之间的差异。
    <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>