0

我需要输出具有正确序列号的附属节点(仅且仅具有“空”子节点的节点)(请参阅 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>
  1. 排序:我需要计算每个位置的每个所属子节点(例如房屋、附属建筑、车辆) 注意,带有 houseWithAC 子节点的房屋算作两个节点! 序列格式为 Loc ### / Item ###

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

1 回答 1

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>
于 2012-07-20T16:39:12.967 回答