我有一些输入长(大约 3k 行)的 XML 文档,通常看起来像:
<chapter someAttributes="someValues">
<title>someTitle</title>
<p>multiple paragraphs</p>
<p>...</p>
<li>
<p>- some text</p>
</li>
<li>
<p>- some other text</p>
</li>
<!-- another li elements -->
<p>multiple other paragraphs</p>
<p>...</p>
<li>
<p>1. some text</p>
</li>
<li>
<p>2. some other text</p>
</li>
<!-- another li elements -->
<p>multiple other paragraphs</p>
<p>...</p>
<!-- there are other elements such as table, illustration, ul etc. -->
</chapter>
我想要的是用 ol
或 ul
元素取决于某些语义并返回包装的 XML。
- 如果段落中的第一个字符等于
-
,那么它应该是带有mark="DASH"
属性的ul
- 如果段落以
1.
、2.
、3.
等开头,那么我想要ol
numeration="阿拉伯语"
例如(这只是一个序列):
<ul mark="DASH">
<li>
<p> some text</p>
</li>
<li>
<p> some other text</p>
</li>
<ul>
正如您进一步看到的,我需要从所有段落中剪切“标记字符”,即-
或1.
, 2.
, 3.
等
该输入 XML 比我描述的更复杂(嵌套序列、表元素中的内部序列),但我正在寻找一些想法,尤其是如何捕获和处理具有这种语义的特定序列。
我希望输出 XML 具有完全相同的顺序,只是带有包装的 li
元素。如果需要,可提供 XSLT 2.0/EXSLT。
最佳答案
这是一个 XSLT 2.0 样式表:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="chapter">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::li)">
<xsl:choose>
<xsl:when test="current-grouping-key() and ./p[1][starts-with(., '-')]">
<ul mark="DASH">
<xsl:apply-templates select="current-group()"/>
</ul>
</xsl:when>
<xsl:when test="current-grouping-key() and ./p[1][matches(., '[0-9]\.')]">
<ol numeration="arabic">
<xsl:apply-templates select="current-group()"/>
</ol>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="li/p/text()[1]">
<xsl:value-of select="replace(., '^(-|[0-9]\.)', '')"/>
</xsl:template>
</xsl:stylesheet>
当我将 Saxon 9.3 与该样式表和示例输入一起使用时
<chapter someAttributes="someValues">
<title>someTitle</title>
<p>multiple paragraphs</p>
<p>...</p>
<li>
<p>- some text</p>
</li>
<li>
<p>- some other text</p>
</li>
<!-- another li elements -->
<p>multiple other paragraphs</p>
<p>...</p>
<li>
<p>1. some text</p>
</li>
<li>
<p>2. some other text</p>
</li>
<!-- another li elements -->
<p>multiple other paragraphs</p>
<p>...</p>
<!-- there are other elements such as table, illustration, ul etc. -->
</chapter>
我得到以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<chapter>
<title>someTitle</title>
<p>multiple paragraphs</p>
<p>...</p>
<ul mark="DASH">
<li>
<p> some text</p>
</li>
<li>
<p> some other text</p>
</li>
</ul>
<p>multiple other paragraphs</p>
<p>...</p>
<ol numeration="arabic">
<li>
<p> some text</p>
</li>
<li>
<p> some other text</p>
</li>
</ol>
<p>multiple other paragraphs</p>
<p>...</p>
</chapter>
关于xml - 使用 XSL 转换(XML 到 XML)包装多个列表元素序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6234913/