【问题标题】:如何使用 XSLT 转换已转换的 XML
【发布时间】:2015-07-11 19:34:18
【问题描述】:

目前我的 XSLT 中有以下结构:

<xsl:template match="/" xml:space="preserve">
    <html>
        <head>
            <!--stuff here -->
        </head>
        <body>
            <!--stuff here -->
            <xsl:call-template name="page-content" />
            <!--stuff here -->
        </body>
    </html>
</xsl:template>

上述文件正在被其他 XSLT 文件导入,这些文件实现了page-content 模板。这是一个示例页面内容模板:

<xsl:template name="page-content">
<div class="main-container">
    <div class="row">
         <xsl:apply-templates select="data/document/content/node()" mode="copy" />
    </div>
</div>
</xsl:template>

我想获取page-content 返回的转换后的 XML,并匹配另一个模板。 (模板将向“主容器”添加另一个节点)。我正在使用 XSLT 3.0

我是否可以将 XML 转换两次,如果可以,我该怎么做?

【问题讨论】:

  • 你的描述让我有些困惑。通常,您可以将转换结果放在变量中,而不是将其写入输出。然后对变量的内容应用另一个转换。
  • @michael.hor257k 我是这门语言的新手,所以我的术语不太好,抱歉。如果我明白你在说什么,我应该用&lt;xsl:variable&gt; 包围&lt;xsl:call-template&gt;,然后在上面调用&lt;xsl:apply-templates&gt;?如果是这样,您能否提供一个如何在变量上调用应用模板的示例?
  • 请编辑您的问题并包含 XML 输入的minimal, complete and verifiable sample、涉及的所有 XSLT 样式表以及您期望的输出。
  • 我可以提供一个 simple 示例 - 但您拥有多个 XSLT 文件会使事情复杂化。而且您没有向我们展示它们之间的确切关系。
  • @michael.hor257k 我可以处理多个 XSLT 文件。一个简单的例子对我来说听起来不错。我想在这里学习概念,而不是找人为我编写代码。

标签: xml xslt


【解决方案1】:

这是一个简单(而且非常人为)的例子:

XML

<lines>
    <line id="1"/>
    <line id="2"/>
    <line id="3"/>
    <line id="4"/>
    <line id="5"/>
    <line id="6"/>
    <line id="7"/>
    <line id="8"/>
    <line id="9"/>
    <line id="10"/>
    <line id="11"/>
    <line id="12"/>
    <line id="13"/>
    <line id="14"/>
    <line id="15"/>
    <line id="16"/>
    <line id="17"/>
    <line id="18"/>
    <line id="19"/>
    <line id="20"/>
    <line id="21"/>
    <line id="22"/>
    <line id="23"/>
    <line id="24"/>
    <line id="25"/>
</lines>

XSLT 2.0

<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="/lines">
    <!-- first-pass -->
    <xsl:variable name="pages">
        <xsl:call-template name="paginate">
            <xsl:with-param name="lines" select="line"/>
        </xsl:call-template>
    </xsl:variable>
    <!-- output -->
    <output>
        <xsl:apply-templates select="$pages"/>
    </output>
</xsl:template>

<xsl:template match="page">
    <xsl:copy>
        <xsl:attribute name="number">
            <xsl:number/>
        </xsl:attribute>
        <xsl:copy-of select="line"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="paginate">
    <xsl:param name="lines"/>
    <xsl:param name="pagesize" select="10"/>
    <page>
        <xsl:copy-of select="$lines[position() le $pagesize]"/>
    </page>
    <xsl:if test="count($lines) gt $pagesize">
        <xsl:call-template name="paginate">
            <xsl:with-param name="lines" select="$lines[position() gt $pagesize]"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <page number="1">
      <line id="1"/>
      <line id="2"/>
      <line id="3"/>
      <line id="4"/>
      <line id="5"/>
      <line id="6"/>
      <line id="7"/>
      <line id="8"/>
      <line id="9"/>
      <line id="10"/>
   </page>
   <page number="2">
      <line id="11"/>
      <line id="12"/>
      <line id="13"/>
      <line id="14"/>
      <line id="15"/>
      <line id="16"/>
      <line id="17"/>
      <line id="18"/>
      <line id="19"/>
      <line id="20"/>
   </page>
   <page number="3">
      <line id="21"/>
      <line id="22"/>
      <line id="23"/>
      <line id="24"/>
      <line id="25"/>
   </page>
</output>

第一遍将行分成 10 组;然后第二遍处理组。

【讨论】:

    【解决方案2】:

    您的思路是正确的:简单转换的管道是实现复杂转换的正确方法,尤其是当它允许您重用管道的组件时。因为样式表本质上是一个函数(输出是输入的函数),所以流水线相当于功能组合(将一个函数应用于另一个函数的结果)。

    有两种组织转换管道的方法,“单样式表”和“多样式表”。在第一种情况下,就像这里一样,您捕获将模板应用到变量中保存的临时树的结果,然后将模板应用到该变量,通常以不同的模式(以确保模板规则仅适用于一个处理阶段)。在第二种情况下,您编写单独的样式表,并将一个应用于另一个的输出,使用另一种语言(Java、Ant、XProc、shell-script)进行协调。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-30
      • 2021-12-22
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多