XSLT - 将模板应用于子节点和 text() 节点
XSLT - apply-templates to child node and text() node
我有一个这样的 xml 文件,
<content>
<ol>
<li> List<span style="color: rgb(255,0,255);">The scopeeeee of</span>this project is
<ol>
<li>nested list1</li>
<li>nested <span style="color: rgb(255,0,255);">The scope of this project is</span> list1</li>
<li>nested list1</li>
<li>nested list1</li>
<li>nested list1</li>
</ol>
</li>
<li>
<p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
</li>
<li>
<p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
</li>
</ol>
</content>
我需要使用 XSLT
将 xml 以上转换为以下 xml
预期输出,
<content>
<orderedList>
<liItem>
<para>List<c type="color: rgb(255,0,255);">The scopeeeee of this project is to:</c>jkhsdlkjfh</para>
</liItem>
<orderedList>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
</orderedList>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
</liItem>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
</liItem>
</orderedList>
</content>
如您所见,li 项中的文本内容和跨度节点必须在输出中覆盖 <para>
个节点。
我已经编写了以下 xsl 以获得此输出,
<xsl:template match="ol">
<orderedList>
<xsl:apply-templates/>
</orderedList>
</xsl:template>
<xsl:template match="li[not(descendant::ol)]" >
<liItem>
<para>
<xsl:apply-templates />
</para>
</liItem>
</xsl:template>
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[parent::li][following-sibling::ol]"/>
</para>
</liItem>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="span">
<c type="{@style}">
<xsl:apply-templates/>
</c>
</xsl:template>
<xsl:template match="li/p">
<xsl:apply-templates />
</xsl:template>
上述 xsl 的唯一问题是当它在另一个 <ol>
项中包含 <ol>
时。我正在努力寻找将 <para>
节点添加到 <li>
和 <ol>
节点之间的文本内容的方法。
当前输出如下,
<content>
<orderedList>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is</para>
</liItem> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is
<orderedList>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para></liItem>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested list1</para></liItem>
</orderedList>
<liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
<liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
</orderedList>
</content>
任何人都可以建议我如何修改我的代码以获得预期的输出..
如果 ol
元素总是出现在 li
元素中的文本之后,您可以将模板更改为此
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[following-sibling::ol]"/>
</para>
</liItem>
<xsl:apply-templates select="ol"/>
</xsl:template>
或者也许是这样,如果您确实想要 liItem
中的 ol
元素但不在 para
中
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[following-sibling::ol]"/>
</para>
<xsl:apply-templates select="ol"/>
</liItem>
</xsl:template>
无论哪种情况,您都可以将匹配 li
的两个模板合并为一个模板;像这样:
<xsl:template match="li" >
<liItem>
<para>
<xsl:apply-templates select="node() except ol"/>
</para>
<xsl:apply-templates select="ol"/>
</liItem>
</xsl:template>
或者,如果您想处理单个列表项中的多个 ol
元素,或者如果您在 ol
元素之后也有文本,您可以使用 xsl:for-each-group
<xsl:template match="li" >
<liItem>
<xsl:for-each-group select="node()" group-adjacent="boolean(self::ol)">
<xsl:choose>
<xsl:when test="current-grouping-key() or not(normalize-space())">
<xsl:apply-templates select="current-group() "/>
</xsl:when>
<xsl:otherwise>
<para>
<xsl:apply-templates select="current-group() "/>
</para>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</liItem>
</xsl:template>
我有一个这样的 xml 文件,
<content>
<ol>
<li> List<span style="color: rgb(255,0,255);">The scopeeeee of</span>this project is
<ol>
<li>nested list1</li>
<li>nested <span style="color: rgb(255,0,255);">The scope of this project is</span> list1</li>
<li>nested list1</li>
<li>nested list1</li>
<li>nested list1</li>
</ol>
</li>
<li>
<p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
</li>
<li>
<p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
</li>
</ol>
</content>
我需要使用 XSLT
将 xml 以上转换为以下 xml预期输出,
<content>
<orderedList>
<liItem>
<para>List<c type="color: rgb(255,0,255);">The scopeeeee of this project is to:</c>jkhsdlkjfh</para>
</liItem>
<orderedList>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
<liItem>
<para>nested list1</para>
</liItem>
</orderedList>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
</liItem>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
</liItem>
</orderedList>
</content>
如您所见,li 项中的文本内容和跨度节点必须在输出中覆盖 <para>
个节点。
我已经编写了以下 xsl 以获得此输出,
<xsl:template match="ol">
<orderedList>
<xsl:apply-templates/>
</orderedList>
</xsl:template>
<xsl:template match="li[not(descendant::ol)]" >
<liItem>
<para>
<xsl:apply-templates />
</para>
</liItem>
</xsl:template>
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[parent::li][following-sibling::ol]"/>
</para>
</liItem>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="span">
<c type="{@style}">
<xsl:apply-templates/>
</c>
</xsl:template>
<xsl:template match="li/p">
<xsl:apply-templates />
</xsl:template>
上述 xsl 的唯一问题是当它在另一个 <ol>
项中包含 <ol>
时。我正在努力寻找将 <para>
节点添加到 <li>
和 <ol>
节点之间的文本内容的方法。
当前输出如下,
<content>
<orderedList>
<liItem>
<para> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is</para>
</liItem> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is
<orderedList>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para></liItem>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested list1</para></liItem>
<liItem><para>nested list1</para></liItem>
</orderedList>
<liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
<liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
</orderedList>
</content>
任何人都可以建议我如何修改我的代码以获得预期的输出..
如果 ol
元素总是出现在 li
元素中的文本之后,您可以将模板更改为此
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[following-sibling::ol]"/>
</para>
</liItem>
<xsl:apply-templates select="ol"/>
</xsl:template>
或者也许是这样,如果您确实想要 liItem
中的 ol
元素但不在 para
<xsl:template match="li[descendant::ol]" >
<liItem>
<para>
<xsl:apply-templates select="node()[following-sibling::ol]"/>
</para>
<xsl:apply-templates select="ol"/>
</liItem>
</xsl:template>
无论哪种情况,您都可以将匹配 li
的两个模板合并为一个模板;像这样:
<xsl:template match="li" >
<liItem>
<para>
<xsl:apply-templates select="node() except ol"/>
</para>
<xsl:apply-templates select="ol"/>
</liItem>
</xsl:template>
或者,如果您想处理单个列表项中的多个 ol
元素,或者如果您在 ol
元素之后也有文本,您可以使用 xsl:for-each-group
<xsl:template match="li" >
<liItem>
<xsl:for-each-group select="node()" group-adjacent="boolean(self::ol)">
<xsl:choose>
<xsl:when test="current-grouping-key() or not(normalize-space())">
<xsl:apply-templates select="current-group() "/>
</xsl:when>
<xsl:otherwise>
<para>
<xsl:apply-templates select="current-group() "/>
</para>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</liItem>
</xsl:template>