需要使用XSLT将以下XML代码段转换为DITA。我的要求是: 1.所有标签都来自" orderedlist"应该包含在" context"节点。 2.所有标签都来自" orderedlist"应该在"结果"。 3.所有"包括"标签应该包含在它们之前的兄弟节点下。
XML:
<?xml version="1.0" encoding="UTF-8"?>
<procedure>
<para>This is first para</para>
<para>This is second para</para>
<include>This is include</include>
<orderedlist>
<listitem>this is list item</listitem>
<include>This is include</include>
<listitem>this is list item <include>this is include</include></listitem>
</orderedlist>
<observation>this is observation</observation>
<para>this is result para <include>this is include</include></para>
<include>This is include</include>
</procedure>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<task>
<context>
<p>This is first para</p>
<p>This is second para <included type='tag'>This is include</included>
</p>
</context>
<ol>
<li>this is list item <included type='tag'>This is include</included>
</li>
<li>this is list item <included type='tag'>this is include</included></li>
</ol>
<result>
<observation>this is observation</observation>
<p>this is result para <included type='tag'>this is include</included><included type='tag'>this is include</included>
</p>
</result>
</task>
我的XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="procedure">
<task>
<context>
<xsl:apply-templates select="*[parent::procedure][following-sibling::orderedlist]"/>
</context>
<xsl:apply-templates select="orderedlist"/>
<result>
<xsl:apply-templates select="*[parent::procedure][preceding-sibling::orderedlist]"/>
</result>
</task>
</xsl:template>
<xsl:template match="para">
<p>
<xsl:apply-templates/>
<include>
<xsl:apply-templates select="following-sibling::include"/>
</include>
</p>
</xsl:template>
<!-- rest of the template goes here -->
<xsl:template match="listitem">
<li>
<xsl:apply-templates/>
<include>
<xsl:apply-templates select="following-sibling::include"/>
</include>
</li>
</xsl:template>
</xsl:stylesheet>
任何指针都会有很大的帮助。感谢。
答案 0 :(得分:2)
首先要注意的是,您可以简化以下表达式:
<xsl:apply-templates select="*[parent::procedure][following-sibling::orderedlist]"/>
此处不需要[parent::procedure]
,因为您已经定位在过程元素上,因此您知道如果选择任何子元素,它会将其作为父!
<xsl:apply-templates select="*[following-sibling::orderedlist]"/>
但是,您可能需要添加一个子句以确保此时不输出 include 元素,因为您需要使用特殊代码来处理它们以后再包含
<xsl:template match="include" />
要处理 include 元素,可能值得定义一个键,因此您可以通过第一个最多程序的非包含元素对它们进行分组,如此
<xsl:key name="include" match="include" use="generate-id(preceding-sibling::*[not(self::include)][1])"/>
然后,在匹配 para 或 listitem 等元素时,您可以获得要包含的 include 元素,如下所示:
<xsl:copy-of select="key('include', generate-id())"/>
注意我不确定如何处理单个元素的multipe include 元素,但在我的示例中,它将单独输出它们与合并它们相反:
这是完整的XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="include" match="include" use="generate-id(preceding-sibling::*[not(self::include)][1])"/>
<xsl:template match="procedure">
<task>
<context>
<xsl:apply-templates select="*[following-sibling::orderedlist]"/>
</context>
<xsl:apply-templates select="orderedlist"/>
<result>
<xsl:apply-templates select="*[preceding-sibling::orderedlist]"/>
</result>
</task>
</xsl:template>
<xsl:template match="orderedlist">
<ol>
<xsl:apply-templates />
</ol>
</xsl:template>
<xsl:template match="para">
<p>
<xsl:apply-templates/>
<xsl:copy-of select="key('include', generate-id())" />
</p>
</xsl:template>
<xsl:template match="listitem">
<li>
<xsl:apply-templates/>
<xsl:copy-of select="key('include', generate-id())" />
</li>
</xsl:template>
<xsl:template match="include" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<task>
<context>
<p>This is first para</p>
<p>This is second para<include>This is include</include></p>
</context>
<ol>
<li>this is list item<include>This is include</include></li>
<li>this is list item</li>
</ol>
<result>
<observation>this is observation</observation>
<p>this is result para<include>This is include</include></p>
</result>
</task>
答案 1 :(得分:1)
尝试一下:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()" name="Copy">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:call-template name="Include" />
</xsl:copy>
</xsl:template>
<xsl:template match="procedure">
<task>
<context>
<xsl:apply-templates select="*[following-sibling::orderedlist]"/>
</context>
<xsl:apply-templates select="orderedlist"/>
<result>
<xsl:apply-templates select="*[preceding-sibling::orderedlist]"/>
</result>
</task>
</xsl:template>
<xsl:template match="para">
<p>
<xsl:apply-templates/>
<xsl:call-template name="Include" />
</p>
</xsl:template>
<!-- rest of the template goes here -->
<xsl:template match="listitem">
<li>
<xsl:apply-templates/>
<xsl:call-template name="Include" />
</li>
</xsl:template>
<xsl:template name="Include">
<xsl:apply-templates
select="following-sibling::include[
generate-id(preceding-sibling::*[not(self::include)][1]) =
generate-id(current())]"
mode="performIncludes"/>
</xsl:template>
<xsl:template match="include" />
<xsl:template match="include" mode="performIncludes">
<xsl:call-template name="Copy" />
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时的输出:
<task>
<context>
<p>This is first para</p>
<p>This is second para<include>This is include</include></p>
</context>
<orderedlist>
<li>this is list item<include>This is include</include></li>
<li>this is list item</li>
</orderedlist>
<result>
<observation>this is observation</observation>
<p>this is result para<include>This is include</include></p>
</result>
</task>