xslt - XSLT 转换 xml 带有子列表的列表项
问题描述
将感谢您的帮助。我有如下的xml:
<ul>
<li>list item 1 </li>
<li>List Item 2
<ul>
<li>List item 2.1</li>
<li>List Item 2.2</li>
</ul>
</li>
<li>List Item 3 </li>
</ul>
输出应如下所示:
<list>
<item>
<paragraph>list item 1 </paragraph>
</item>
<item>
<paragraph>List Item 2 </paragraph>
<list>
<item>
<paragraph>List<emphasis> item</emphasis> 2.1 </paragraph>
</item>
<item>
<paragraph>List Item 2.2 </paragraph>
</item>
</list>
</item>
<item>
<paragraph>List Item 3 </paragraph>
</item>
</list>
我正在使用 xlst 3.0 版,如下所示:
<xsl:template match="ul">
<xsl:choose>
<xsl:when test="name(..)='li'">
<xsl:text disable-output-escaping="yes"></paragraph></xsl:text>
<list>
<xsl:apply-templates/>
</list>
</xsl:when>
<xsl:otherwise>
<list>
<xsl:apply-templates/>
</list></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="li">
<item>
<xsl:text disable-output-escaping="yes"><paragraph></xsl:text>
<xsl:apply-templates/>
<xsl:text disable-output-escaping="yes"></paragraph></xsl:text>
</item>
</xsl:template>
我几乎得到了我想要的输出,但有额外的结束段落元素(</paragraph>
)如下:
<list>
<item><paragraph>list item 1 </paragraph></item>
<item><paragraph>List Item 2 </paragraph><list>
<item><paragraph>List item 2.1 </paragraph></item>
<item><paragraph>List Item 2.2 </paragraph></item>
</list>
</paragraph></item>
<item><paragraph>List Item 3 </paragraph></item>
</list>
解决方案
您应该避免disable-output-escaping
以这种方式使用。正如您所见,这确实不是一个好习惯。
对于给定的 XML,您可以做的是使用匹配的模板,text()
然后将其包装paragraph
起来:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:output method="xml" indent="yes""/>
<xsl:strip-space elements="*" />
<xsl:template match="ul">
<list>
<xsl:apply-templates/>
</list>
</xsl:template>
<xsl:template match="li">
<item>
<xsl:apply-templates/>
</item>
</xsl:template>
<xsl:template match="text()">
<paragraph>
<xsl:value-of select="normalize-space()" />
</paragraph>
</xsl:template>
</xsl:stylesheet>
或者,如果您可以在文本中添加标记,例如<li>list <b>item 1</b> </li>
,并且您想要输出类似<paragraph>list<b>item 1</b></paragraph>
,那么您可以使用xsl:for-each-group
.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="ul">
<list>
<xsl:apply-templates/>
</list>
</xsl:template>
<xsl:template match="li">
<item>
<xsl:for-each-group select="node()" group-ending-with="ul">
<paragraph>
<xsl:apply-templates select="current-group()[not(self::ul)]" />
</paragraph>
<xsl:apply-templates select="current-group()[self::ul]" />
</xsl:for-each-group>
</item>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space()" />
</xsl:template>
</xsl:stylesheet>
推荐阅读
- angular - Angular - MongoDB 直接 CRUD
- c++ - 分段错误背包问题
- angular - 更改 amcharts 缩放范围填充颜色
- c# - 使用 DependencyResolver 会导致性能下降吗?
- asp.net - 任何 REST API,它为我们提供了在 azure 中支持超磁盘的区域列表
- angular - 如何以 Angular 8 形式生成 csrf 令牌以及如何在 laravel 的 api.php 文件中使用中间件 cors 编写路由?
- javascript - 如何使用javascript为负或正十进制值编写正则表达式
- python - 尝试使用天空场时出现错误“没有名为 jplephem.pck 的模块”
- javascript - 在 Highcharts 中正确显示 Xvalues 数据
- node.js - 在 MongoDB 中再次聚合 + $project + $group + $sum + $count + $group