使用 XSLT 2.0 将 XML 分成多个部分
Break up XML into parts using XSLT 2.0
我得到 XML 作为输入,我无法控制结构。我需要将 XML 分成几个部分并分别处理每个部分。下面是我要处理的文件的一个非常简化的版本。
我正在尝试使用 XSLT 2.0 的分组功能通过使用 <breakEle>
标记作为部分边界来分解此 XML。 <breakEle>
也可以出现在任何级别。使用 XSLT 2.0 甚至可以实现我正在尝试做的事情吗?我已经通过使用 Muenchian 分组的 XSLT 1.0 成功地实现了这一点,但如果可以的话,我想摆脱它。
示例输入:
<item class="poem">
<div>
<div>
<p>paragraph 1</p>
<breakEle groupNum="1"/>
</div>
<div>
<p>Paragraph in another div.</p>
</div>
<breakEle groupNum="2"/>
<div>
<div>
<h4>header</h4>
<p>1st line</p>
<p>2nd line</p>
<br/>
<p>3rd line</p>
<p>4th line</p>
<page n="100"/>
<p>5th line</p>
</div>
<breakEle groupNum="3"/>
</div>
</div>
</item>
我正在尝试使用什么:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
exclude-result-prefixes="xs xd"
version="2.0">
<xsl:template match="/">
<newRoot>
<xsl:copy>
<xsl:for-each-group select="*" group-ending-with="breakEle">
<div num="{@groupNum}">
<xsl:copy-of select="current-group()"/>
</div>
</xsl:for-each-group>
</xsl:copy>
</newRoot>
</xsl:template>
</xsl:stylesheet>
想以这样的方式结束:
<newRoot>
<div num="1">
<p>paragraph 1</p>
</div>
<div num="2">
<p>Paragraph in another div.</p>
</div>
<div num="3">
<h4>header</h4>
<p>1st line</p>
<p>2nd line</p>
<br/>
<p>3rd line</p>
<p>4th line</p>
<page n="100"/>
<p>5th line</p>
</div>
</newRoot>
以下样式表 returns 应用于给定示例时的预期结果。
它的工作假设是每个组只应包含叶元素。
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:strip-space elements="*"/>
<xsl:template match="/item">
<newRoot>
<xsl:for-each-group select=".//*[not(*)]" group-ending-with="breakEle">
<div num="{current-group()[last()]/@groupNum}">
<xsl:copy-of select="current-group()[not(self::breakEle)]"/>
</div>
</xsl:for-each-group>
</newRoot>
</xsl:template>
</xsl:stylesheet>
我得到 XML 作为输入,我无法控制结构。我需要将 XML 分成几个部分并分别处理每个部分。下面是我要处理的文件的一个非常简化的版本。
我正在尝试使用 XSLT 2.0 的分组功能通过使用 <breakEle>
标记作为部分边界来分解此 XML。 <breakEle>
也可以出现在任何级别。使用 XSLT 2.0 甚至可以实现我正在尝试做的事情吗?我已经通过使用 Muenchian 分组的 XSLT 1.0 成功地实现了这一点,但如果可以的话,我想摆脱它。
示例输入:
<item class="poem">
<div>
<div>
<p>paragraph 1</p>
<breakEle groupNum="1"/>
</div>
<div>
<p>Paragraph in another div.</p>
</div>
<breakEle groupNum="2"/>
<div>
<div>
<h4>header</h4>
<p>1st line</p>
<p>2nd line</p>
<br/>
<p>3rd line</p>
<p>4th line</p>
<page n="100"/>
<p>5th line</p>
</div>
<breakEle groupNum="3"/>
</div>
</div>
</item>
我正在尝试使用什么:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
exclude-result-prefixes="xs xd"
version="2.0">
<xsl:template match="/">
<newRoot>
<xsl:copy>
<xsl:for-each-group select="*" group-ending-with="breakEle">
<div num="{@groupNum}">
<xsl:copy-of select="current-group()"/>
</div>
</xsl:for-each-group>
</xsl:copy>
</newRoot>
</xsl:template>
</xsl:stylesheet>
想以这样的方式结束:
<newRoot>
<div num="1">
<p>paragraph 1</p>
</div>
<div num="2">
<p>Paragraph in another div.</p>
</div>
<div num="3">
<h4>header</h4>
<p>1st line</p>
<p>2nd line</p>
<br/>
<p>3rd line</p>
<p>4th line</p>
<page n="100"/>
<p>5th line</p>
</div>
</newRoot>
以下样式表 returns 应用于给定示例时的预期结果。
它的工作假设是每个组只应包含叶元素。
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:strip-space elements="*"/>
<xsl:template match="/item">
<newRoot>
<xsl:for-each-group select=".//*[not(*)]" group-ending-with="breakEle">
<div num="{current-group()[last()]/@groupNum}">
<xsl:copy-of select="current-group()[not(self::breakEle)]"/>
</div>
</xsl:for-each-group>
</newRoot>
</xsl:template>
</xsl:stylesheet>