XSLT 处理所有节点,直到到达具有特定名称的节点



我有以下xml结构:

    <?xml version="1.0"?>
<items>
    <item/>
    <desc/>
    <desc2/>
    <desc3/>
    <price1/>
    <info/>
    <info/>
    <info2/>
    <item/>
    <desc/>
    <price1/>
    <price2/>
    <price3/>
    <info1/>
    <anotheriinfo/>
    <specialinfo/>
    <item/>
    <desc/>
    <price1/>
</items>

其中<item>不是以下节点的父节点。我需要使用相应的信息和定价对不同的项目进行分组。有没有办法在下一个<item>之前选择<item>和所有后续节点并应用一些 logig ?或者将它们分组为喜欢

   <?xml version="1.0" encoding="UTF-8"?>
<items>
  <item>
    <desc/>
    <desc2/>
    <desc3/>
    <price1/>
    <info/>
    <info/>
    <info2/>
  </item>
  <item>
    <desc/>
    <price1/>
    <price2/>
    <price3/>
    <info1/>
    <anotheriinfo/>
    <specialinfo/>
  </item>
  <item>
    <desc/>
    <price1/>
  </item>
</items>

我需要使用 XSLT 1.0

您可能

想在这里阅读和应用的三种技术。

  • 如果您只需要在显示 item 元素之前有一个空行(如"或将它们分组为..."所建议的那样(,请编写样式表以发出该值。

  • 阅读Muenchian分组;要分组的值是前面命名为item的同级的数量(对于本身未命名为item的节点(或名为item加一的前一个同级数(对于item元素(。

  • 学习执行树遍历,方法是先对其子级进行模板调用,然后对其直接右同级进行模板调用apply-templates。 在这种情况下,基本模式是

    <xsl:template match="items">
      <xsl:apply-templates match="item"/>
    </
    <xsl:template match="item">  
      <xsl:copy>
        <!-- handle descendants, if your current items have any ... --> 
        <xsl:apply-templates match="@*|node()"/>
        <!-- bring right siblings into the content ... -->
        <xsl:apply-templates match="following-sibling::*[1]" 
             mode="group-nodes"/>
      </
    </
    <xsl:template match="*" mode="group-nodes" priority="1">
      <!-- 1 handle this element -->
      <!-- modify next line if items elements can nest ... -->
      <xsl:copy-of select="."/>
      <!-- 2 handle next sibling -->
      <xsl:apply-templates match="following-sibling::*[1]" 
             mode="group-nodes"/>
      </
    </
    <xsl:template match="item" mode="group-nodes" priority="10"/>
    

我喜欢带有Muenchian分组的Sperberg-McQueens解决方案。我根据position()和产生预期结果的后续兄弟姐妹的数量,采用了完全不同的方法(再次!!(。只是想分享这个:

<xsl:template match="items">
    <xsl:copy>
        <!-- total number of items -->
        <xsl:variable name="countItems" select="count(item)"/>
        <!-- edit: copy elements before first item -->
        <xsl:copy-of select="*[following-sibling::item[$countItems]]"/>
        <xsl:for-each select="item">
            <!-- position of current item -->
            <xsl:variable name="position" select="position()"/>
            <xsl:choose>
                <xsl:when test="following-sibling::item">
                    <xsl:copy>
                        <!-- get all elements before next item -->
                        <!-- = all elements followed by (total items minus current position) items -->
                        <xsl:apply-templates select="following-sibling::*[following-sibling::item[$countItems - $position]]"/>
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy>
                        <xsl:apply-templates select="following-sibling::*"/>
                    </xsl:copy>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
<!-- identity transform -->
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

相关内容

  • 没有找到相关文章

最新更新