[英]How to transform already transformed XML using XSLT
I currently have the following structure in my XSLT: 我的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>
The above file is being imported by other XSLT files, which implement the page-content
template. 上面的文件正在由其他XSLT文件导入,这些文件实现了
page-content
模板。 Here's a sample page-content template: 这是示例页面内容模板:
<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>
I want to take the transformed XML returned by page-content
, and match another template to it. 我想获取
page-content
返回的转换后的XML,并将另一个模板与其匹配。 (The template is going to add another node to "main-container"). (模板将向“ main-container”添加另一个节点)。 I am using XSLT 3.0
我正在使用XSLT 3.0
Is it possible for me to transform XML twice, and if so, how do I do it? 我是否可以两次转换XML,如果可以,我该怎么做?
Here's a simple (and very artificial) example: 这是一个简单的(非常人为的)示例:
XML 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 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>
Result 结果
<?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>
The first pass divides the lines into groups of 10; 第一遍将线分为10组; then the second pass processes the groups.
然后第二遍处理组。
You're thinking on the right lines: pipelines of simple transformations are the right way to implement a complex transformation, especially when it allows you to reuse the components of the pipeline. 您正在考虑正确的路线:简单转换的管道是实现复杂转换的正确方法,尤其是当它允许您重用管道的组件时。 Because a stylesheet is essentially a function (the output is a function of the input), pipelining is equivalent to functional composition (applying one function to the result of another).
因为样式表本质上是一个函数(输出是输入的函数),所以流水线等效于功能组合(将一个函数应用于另一个函数的结果)。
There are two ways of organizing a pipeline of transformations, "single-stylesheet" and "multiple-stylesheet". 有两种组织转换管道的方式,“单个样式表”和“多个样式表”。 In the first case, as here, you capture the result of applying templates into a temporary tree held in a variable, and then you apply-templates to that variable, often in a different mode (to make sure that template rules apply only to one phase of processing).
在第一种情况下,如此处所示,您捕获了将模板应用于变量中包含的临时树的结果,然后将模板应用于该变量,通常采用不同的模式(以确保模板规则仅适用于一个处理阶段)。 In the second case, you write separate stylesheets, and apply one to the output of another, using another language (Java, Ant, XProc, shell-script) to do the coordination.
在第二种情况下,您编写单独的样式表,然后使用另一种语言(Java,Ant,XProc,shell脚本)将样式表应用于另一个样式表的输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.