首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT将线性结构转换为非线性结构

XSLT将线性结构转换为非线性结构
EN

Stack Overflow用户
提问于 2014-06-10 03:04:08
回答 4查看 200关注 0票数 1

我已经和XML

代码语言:javascript
复制
<main>
    <div type='scene'>
        <l>l1</l>
        <sp>A speach</sp>
        <l>l2</l>
        <pb />
        <l>l3</l>
       <l>14</l>
    </div>
</main>

我的任务是将它转换为

代码语言:javascript
复制
<div class="line-group">
    <l>l1</l>
    <div class="speach">
       A speach
    </div>
    <l>l2</l>
</div>
<div class="line-group">
    <l>l3</l>
    <l>l4</l>
</div>

我知道可能有任意数量的<pb />,只有在没有连续的<pb />和在开始和结束时都没有<pb />的情况下,才能正确地实现此输出。

但是,我们可以使用这种方法将所有<pb />替换为</div><div class="line-group">,并在开始时使用<div class="line-group">,在结束时使用</div>

我如何在XSLT中做到这一点?

我已经为所有其他标签提供了模板,我在示例中使用了sp来显示<l>不是唯一的子项。

EN

回答 4

Stack Overflow用户

发布于 2014-06-10 03:27:29

可以定义一个关键点,以便根据每个场景中最近的前一个pb元素的pb元素将这些非pb元素聚集到组中。

代码语言:javascript
复制
<xsl:key name="elByPb" match="*[not(self::pb)]"
                       use="concat(generate-id(..), '|',
                                   generate-id(preceding-sibling::pb[1]))" />

现在,要处理场景,您需要在第一个pb之前为元素创建一个line-group,然后在每个pb之后创建另一个元素

代码语言:javascript
复制
<xsl:template match="div[@type='scene']">
  <xsl:copy>
    <xsl:copy-of select="@*" />
    <xsl:call-template name="line-group">
      <xsl:with-param name="groupKey" select="concat(generate-id(), '|')" />
    </xsl:call-template>
    <xsl:apply-templates select="pb" />
  </xsl:copy>
</xsl:template>

<xsl:template match="pb" name="line-group">
  <xsl:param name="groupKey"
             select="concat(generate-id(..), '|', generate-id())" />
  <div class="line-group">
    <xsl:apply-templates select="key('elByPb', $groupKey)" />
  </div>
</xsl:template>

在这里,我利用了这样一个事实,即空节点集的generate-id (根据定义)是空字符串,因此节中第一个pb之前的元素将在"id-of-parent|"上设置键值

票数 2
EN

Stack Overflow用户

发布于 2014-06-10 03:39:46

代码语言:javascript
复制
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="div">
<xsl:for-each-group select="*" group-ending-with="pb">
<div class="line-group">
 <xsl:apply-templates select="current-group()"/>
 </div>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="pb"></xsl:template>
<xsl:template match="l">

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

票数 2
EN

Stack Overflow用户

发布于 2014-06-10 04:31:59

可以使用disable-output-escape=‘yes’,但这不是一种优雅的方法。

代码语言:javascript
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="div">
<root>
<xsl:text disable-output-escaping="yes">&lt;div class=&quot;line-group&quot;></xsl:text>
          <xsl:apply-templates/>
<xsl:text disable-output-escaping="yes">&lt;/div></xsl:text>  
</root>
</xsl:template> 

<xsl:template match="pb">
  <xsl:text disable-output-escaping="yes">&lt;/div></xsl:text>  <xsl:text disable-output-escaping="yes">&lt;div class=&quot;line-group&quot;></xsl:text>
</xsl:template>
<xsl:template match="l">
     <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
     </xsl:copy>   
</xsl:template>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24127128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档