我尝试按标题对元素进行分组。 我目前的解决方案有一个缺点。下一个标题及其内容嵌套在前一个的body标签中。 是否可以仅嵌套body标签中的内容而不是下一组? 有没有人有想法或建议? 它应该看起来像所需的结果。
来源
<?xml version="1.0" encoding="UTF-8"?>
<html>
<title>headline</title>
<body>
<h1 name="d1e25">H1</h1>
<p>p</p>
<h2 name="d1e25">H2</h2>
<p>p</p>
<h3 name="d1e25">H3</h3>
<p>p</p>
<h3 name="d1e25">H3</h3>
<p>p</p>
<h4 name="d1e25">H4</h4>
<p>p</p>
<h2 name="d1e25">H2</h2>
<table></table>
</body>
</html>
我的转型
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:function name="mf:group" as="node()*">
<xsl:param name="elements" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
<xsl:choose>
<xsl:when test="self::*[local-name() eq concat('h', $level)]">
<topic>
<xsl:attribute name="id"><xsl:copy-of select="@name"/></xsl:attribute>
<xsl:element name="title"><xsl:value-of select="." /></xsl:element>
<body>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</body>
</topic>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/html">
<topic>
<xsl:attribute name="id">
<xsl:attribute name="id" select="generate-id()" />
</xsl:attribute>
<xsl:copy-of select="title"/>
<xsl:apply-templates select="body"/>
</topic>
</xsl:template>
<xsl:template match="body">
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:template>
</xsl:transform>
我从以下帖子中得到了这个 grouping following-siblings with same name and same attributes causes exception in saxon
我的结果
<topic id="d1e1">
<title>headline</title>
<topic id="d1e25">
<title>H1</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H2</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
</body>
</topic>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H4</title>
<body>
<p>p</p>
</body>
</topic>
</body>
</topic>
</body>
</topic>
<topic id="d1e25">
<title>H2</title>
<body>
<table/>
</body>
</topic>
</body>
</topic>
</topic>
期望的结果
<topic id="d1e1">
<title>headline</title>
<topic id="d1e25">
<title>H1</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H2</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
</body>
</topic>
<topic id="d1e25">
<title>H3</title>
<body>
<p>p</p>
<topic id="d1e25">
<title>H4</title>
<body>
<p>p</p>
</body>
</topic>
</body>
</topic>
</body>
</topic>
<topic id="d1e25">
<title>H2</title>
<body>
<table/>
</body>
</topic>
</body>
</topic>
</topic>
答案 0 :(得分:0)
我有一个解决方案
我的转型
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="html">
<document><xsl:apply-templates/></document>
</xsl:template>
<xsl:template match="body">
<xsl:apply-templates select="h1" />
</xsl:template>
<xsl:key name="next-headings" match="h6"
use="generate-id(preceding-sibling::*[self::h1 or self::h2 or
self::h3 or self::h4 or
self::h5][1])" />
<xsl:key name="next-headings" match="h5"
use="generate-id(preceding-sibling::*[self::h1 or self::h2 or
self::h3 or self::h4][1])" />
<xsl:key name="next-headings" match="h4"
use="generate-id(preceding-sibling::*[self::h1 or self::h2 or
self::h3][1])" />
<xsl:key name="next-headings" match="h3"
use="generate-id(preceding-sibling::*[self::h1 or self::h2][1])" />
<xsl:key name="next-headings" match="h2"
use="generate-id(preceding-sibling::h1[1])" />
<xsl:key name="immediate-nodes"
match="node()[not(self::h1 | self::h2 | self::h3 | self::h4 |
self::h5 | self::h6)]"
use="generate-id(preceding-sibling::*[self::h1 or self::h2 or
self::h3 or self::h4 or
self::h5 or self::h6][1])" />
<xsl:template match="h1 | h2 | h3 | h4 | h5 | h6">
<xsl:variable name="vLevel" select="substring-after(name(), 'h')" />
<topic>
<xsl:element name="title">
<xsl:apply-templates />
</xsl:element>
<body>
<xsl:apply-templates select="key('immediate-nodes', generate-id())" />
</body>
<xsl:apply-templates select="key('next-headings', generate-id())" />
</topic>
</xsl:template>
<xsl:template match="/*/*/node()" priority="-20">
<xsl:copy-of select="." />
</xsl:template>
</xsl:transform>
<强>结果强>
<document>
<topic>
<title>H1</title>
<body>
<p>p</p>
</body>
<topic>
<title>H2</title>
<body>
<p>p</p>
</body>
<topic>
<title>H3</title>
<body>
<p>p</p>
</body>
</topic>
<topic>
<title>H3</title>
<body>
<p>p</p>
</body>
<topic>
<title>H4</title>
<body>
<p>p</p>
</body>
</topic>
</topic>
</topic>
<topic>
<title>H2</title>
<body>
<table/>
</body>
</topic>
</topic>
</document>