1

我正在使用 xslt 2.0,我有以下示例 xml,我想在两个“header-gray”节点之间获取所有“header-lightgray”节点,这里的问题是:我不知道有多少“header-lightgray”那里。所以我不能使用 position() 函数。并且每个 xsl 都不支持中断。

<t>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
...
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
</t>

我想通过它们并替换所有节点,用div替换header-gray和用span替换header-lightgray。预期的输出是:

<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
...
</div>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>

那么该怎么做呢?

任何帮助表示赞赏。

我想根据 Jan Vlcinsky 的回答分享解决方案:

<xsl:for-each select="/t/parent[@class='header-gray']">
  <xsl:variable name="ns1" select="current()/following-sibling::parent"/>
  <xsl:variable name="ns2" select="current()/following-sibling::parent[@class='header-gray'][1]/preceding-sibling::parent"/>
  <div class="header-gray">
  <xsl:for-each select="$ns1[count(.| $ns2)=count($ns2)]">
     <span class="header-lightgray"/>      
  </xsl:for-each>
  </div>
</xsl:for-each>

我没有验证上面的代码,但它在我的真实代码中是相同的逻辑。我没有使用 xslt 2.0 的方式,因为我发现我使用的 lxml 2.3 不支持 xslt 2。

4

3 回答 3

0

查看页面底部的“3.位置分组问题”部分http://gandhimukul.tripod.com/xslt/grouping20.html

您的问题似乎有点重复:您如何使用 XPATH 找到两个 H3 之间的所有节点?

问题XPath:选择所有后续兄弟,直到另一个兄弟也处理相同的问题。

于 2013-05-14T15:04:19.027 回答
0

这种转变

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <t>
   <xsl:for-each-group select="*"
        group-starting-with="parent[@class='header-gray']">
     <div class="header-gray">
       <xsl:apply-templates select="current-group()[position() ne 1]"/>
     </div>
   </xsl:for-each-group>
  </t>
 </xsl:template>

 <xsl:template match="parent">
   <span class="{@class}"/>
 </xsl:template>
</xsl:stylesheet>

当应用于以下 XML 文档(提供的片段,包装到单个顶部元素中,使其成为格式良好的 XML 文档)时:

<t>
    <parent class="header-gray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-gray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-gray"></parent>
</t>

产生想要的正确结果:

<t>
   <div class="header-gray">
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
   </div>
   <div class="header-gray">
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
   </div>
   <div class="header-gray"/>
</t>
于 2013-05-15T04:12:44.647 回答
-1

这是一种方法。

当这个 XSLT 2.0 解决方案:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:strip-space elements="*"/>

   <xsl:template match="/*">
      <t>
         <xsl:apply-templates
           select="parent[@class = 'header-gray'][following-sibling::*]"/>
      </t>
   </xsl:template>

   <xsl:template match="*[@class = 'header-gray']">
      <div class="{@class}">
         <xsl:apply-templates
           select="
             following-sibling::*[@class = 'header-lightgray'] 
               intersect
             following-sibling::*[@class = 'header-gray'][1]/
                 preceding-sibling::*[@class = 'header-lightgray']"/>
      </div>
   </xsl:template>

   <xsl:template match="*[@class = 'header-lightgray']">
      <span class="{@class}"/>
   </xsl:template>

</xsl:stylesheet>

...应用于提供的 XML(包装在顶级元素中以使文档格式正确):

<t>
  <parent class="header-gray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-gray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-gray"/>
</t>

...产生了预期的结果:

<t>
  <div class="header-gray">
    <span class="header-lightgray" />
    <span class="header-lightgray" />
    <span class="header-lightgray" />
  </div>
  <div class="header-gray">
    <span class="header-lightgray" />
    <span class="header-lightgray" />
    <span class="header-lightgray" />
  </div>
</t>

该解决方案利用了XPath 2.0 的相交操作

于 2013-05-14T14:36:48.993 回答