我(遗憾的是)必须使用的软件会生成包含多个数据集的XML文件(请参阅以下示例:“文档1”,“文档2”,...)但不用包装{{1 }} 标签。它看起来像这样:
<document>
正如您所看到的,每个新的“文档”都在其第一个<print>
<section>
<col1>*****</col1>
<col2>Document 1</col2>
</section>
<section>
<col1>Title</col1>
<col2>Title 1</col2>
</section>
<section>
<col1>Year</col1>
<col2>2011</col2>
</section>
<section />
<section>
<col1>*****</col1>
<col2>Document 2</col2>
</section>
<section>
<col1>Title</col1>
<col2>Title 2</col2>
</section>
<section>
<col1>Year</col1>
<col2>2012</col2>
</section>
<section />
<section>
<col1>*****</col1>
<col2>Document 3</col2>
</section>
<section>
<col1>Title</col1>
<col2>Title 3</col2>
</section>
<section>
<col1>Year</col1>
<col2>2013</col2>
</section>
<section />
...
</print>
标记中以<col1>*****</col1>
开头,并以(或更具体:后跟)空<section></section>
结尾标签
我想要做的是取出每个<section />
值并将其放入包装标签,最后我应该得到文档的分离数据集。结果应如下所示:
<col2>
所以我必须获取所有<print>
<document>
<docno>Document 1</docno>
<title>Title 1</title>
<year>2011</year>
</document>
<document>
<docno>Document 2</docno>
<title>Title 2</title>
<year>2012</year>
</document>
<document>
<docno>Document 3</docno>
<title>Title 3</title>
<year>2013</year>
</document>
</print>
值,将它们放入新元素并将它们包装在<col2>
标记中。我尝试使用以下XSLT并且我获得了部分成功(我可以获得<document>
值),但是在<col2>
标记内(我尝试包装<xsl:when>
值)它会抛出错误,因为<col2>
标记未立即关闭:
<document>
我发现在XSLT中,有条件地打开和关闭标签是不可能的,但我确信还有另一种解决方案如何实现我的目标......我只是没有太多经验才能找到它。有人能指出我正确的方向吗?非常感谢你提前!
答案 0 :(得分:1)
如果您可以使用XSLT 2.0,还有更优雅的方法,但如果您知道每个空<section>
元素之间有三个<section/>
个元素,那么您可以做一些简单的事情这(XSLT 1.0兼容):
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="print">
<xsl:copy>
<!--
Only apply the first <section> child of <print> and those <section> children
whose first preceding <section> sibling is an empty <section/> element
-->
<xsl:apply-templates select="section[position() = 1
or preceding-sibling::section[1][not(node())]]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<document>
<!--
Transform the <col2> child of this <section> into a <docno> elemen
-->
<xsl:apply-templates select="col2" mode="number"/>
<!--
Transform the <col2> element of the first following <section> sibling into
a <title> element
-->
<xsl:apply-templates select="following-sibling::section[1]/col2" mode="title"/>
<xsl:apply-templates select="following-sibling::section[2]/col2" mode="year"/>
</document>
</xsl:template>
<xsl:template match="col2" mode="number">
<docno>
<xsl:value-of select="."/>
</docno>
</xsl:template>
<xsl:template match="col2" mode="title">
<title>
<xsl:value-of select="."/>
</title>
</xsl:template>
<xsl:template match="col2" mode="year">
<year>
<xsl:value-of select="."/>
</year>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
使用(在XSLT 2.0中)
<xsl:template match="print">
<xsl:for-each-group select="section"
group-starting-with="section[starts-with(col2, 'Document')]">
<document>
<docno><xsl:value-of select="current-group()[1]/col2"/>
... etc ...
</document>
</xsl:for-each-group>
</xsl:template>