Xslt 如何通过前面的同级循环到一个点

Xslt 如何通过前面的同级循环到一个点,xslt,Xslt,我有以下XML: <p> <span>Foo</span> <br/> </p> <p> <span>Foo</span> <br/> <span>Foo</span> <span>Foo</span> <br/> </p> <p> <

我有以下XML:

<p>
    <span>Foo</span>
    <br/>
</p>

<p>
    <span>Foo</span>
    <br/>
    <span>Foo</span>
    <span>Foo</span>
    <br/>
</p>

<p>
    <span>Foo</span>
    <span>Foo</span>
    <br/>
    <span>Foo</span>
    <span>Foo</span>
    <span>Foo</span>
    <br/>
</p>


福 福

福 福
福 福 福

我希望能够首先选择

标记,然后在它们上面的跨距中循环。这样做的原因是为了去掉

标记,并替换为

标记,如下所示:

<p>
    <span>Foo</span>
</p>

<p>
    <span>Foo</span>
</p>

<p>
    <span>Foo</span>
    <span>Foo</span>
</p>

<p>
    <span>Foo</span>
    <span>Foo</span>
</p>

<p>
    <span>Foo</span>
    <span>Foo</span>
    <span>Foo</span>
</p>

福 福

福 福

福 福 福

这就是我提出的xslt类型:

<xsl:template match="br">
    <p>
    <xsl:for-each select="preceding-sibling::span">
         <span>
         <xsl:value-of select="." />
         </span>
    </xsl:for-each>
    </p>
</xsl:template>


我知道这是错误的,因为它将拾取p标记中的所有跨距,而不仅仅是前一个br标记之前的跨距。任何建议都值得赞赏
提前多谢

实现这一点的一种方法是使用匹配给定br标记之前的所有span

<xsl:key name="para" match="span" use="generate-id(following-sibling::br[1])" />

i、 e将所有span标签按紧随其后的第一个br分组

然后,您可以在br元素上进行匹配,并使用此键获取其前面的所有关联span标记

<xsl:template match="br">
   <p>
      <xsl:apply-templates select="key('para', generate-id())" />
   </p>


以下是完整的XSLT:

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

   <xsl:key name="para" match="span" use="generate-id(following-sibling::br[1])" />

   <xsl:template match="/">
      <body>
         <xsl:apply-templates select="body/p" />
      </body>
   </xsl:template>

   <xsl:template match="p">
      <xsl:apply-templates select="br" />
      <xsl:if test="span[not(following-sibling::br)]">
         <p>
            <xsl:apply-templates select="span[not(following-sibling::br)]" />
         </p>
      </xsl:if>
   </xsl:template>

   <xsl:template match="br">
      <p>
         <xsl:apply-templates select="key('para', generate-id())" />
      </p>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>


当应用于以下输入XML时(我假设您的示例包含在body标记中,使其成为有效的XML

<body>
   <p>
      <span>Foo 1</span>
      <br/>
   </p>
   <p>
      <span>Foo 2</span>
      <br/>
      <span>Foo 3</span>
      <span>Foo 4</span>
      <br/>
   </p>
   <p>
      <span>Foo 5</span>
      <span>Foo 6</span>
      <br/>
      <span>Foo 7</span>
      <span>Foo 8</span>
      <span>Foo 9</span>
      <br/>
      <span>Foo 10</span>
   </p>
</body>


富1

富2
富3 富4

富5 富6
富7 富8 富9
富10

输出如下:

<body>
   <p>
      <span>Foo 1</span>
   </p>
   <p>
      <span>Foo 2</span>
   </p>
   <p>
      <span>Foo 3</span>
      <span>Foo 4</span>
   </p>
   <p>
      <span>Foo 5</span>
      <span>Foo 6</span>
   </p>
   <p>
      <span>Foo 7</span>
      <span>Foo 8</span>
      <span>Foo 9</span>
   </p>
   <p>
      <span>Foo 10</span>
   </p>
</body>


富1

富2

富3 富4

富5 富6

富7 富8 富9

富10

请注意,作为一个例子,我添加了一个案例来处理段落中没有后续br标记的span标记