我经历了XSLT分组的例子和使用的,每个组高性能XSLT 。 我有换各组的问题。
我的XML
<?xml version="1.0" encoding="UTF-8"?>
<body>
<p name="h-title" other="main">Introduction</p>
<p name="h1-title " other="other-h1">XSLT and XQuery</p>
<p name="h2-title" other=" other-h2">XSLT</p>
<p name="">
<p1 name="bold"> XSLT is used to write stylesheets.</p1>
</p>
<p name="h2-title " name="other-h2">XQuery</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h3-title" name="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h1-title " other="other-h1">XSLT and XQuery</p>
<p name="h2-title " other=" other-h2">XSLT</p>
</body>
我的通缉输出
<?xml version="1.0" encoding="UTF-8"?>
<body>
<p name="h-title " other="main">Introduction</p>
<h1>
<p name="h1-title " other="other-h1"> XSLT and XQuery </p>
<h2>
<p name="h2-title " other="other-h2">XSLT</p>
<p name="">
<p1 name="bold">XSLT is used to write stylesheets.
</p1>
</p>
</h2>
<h2>
<p name="h2-title " other="other-h2"> XQuery is used to query XML databases
</p>
<p name="">
<p name="bold"> XQuery is used to query XML databases.</p>
</p>
<h3>
<p name="h3-title " name="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
</h3>
</h2>
</h1>
<h1>
<p name="h1-title " other="other-h1">XSLT and XQuery</p>
<h2>
<p name="h2"-title other=" other-h2">XSLT</p>
</h2>
</h1>
</body>
我想这一点。 (不工作)
<xsl:template match="body">
<body>
<xsl:for-each-group select="*" group-starting-with="@h1-title" >
<h1>
<xsl:for-each select="current-group()[self:: h1-title]">
<xsl:value-of select="."/>
</xsl:for-each>
</h1>
</xsl:for-each-group>
<xsl:for-each-group select="*" group-starting-with="@h2-title" >
<h2>
<xsl:for-each select="current-group()[self::h2-title/@h2-title]">
<xsl:value-of select="."/>
</xsl:for-each>
</h2>
</xsl:for-each-group>
<xsl:for-each-group select="*" group-starting-with="@h3-title" >
<h3>
<xsl:for-each select="current-group()[self::h2-title/@h3-title]">
<xsl:value-of select="."/>
</xsl:for-each>
</h3>
</xsl:for-each-group>
</body>
</xsl:template>
会有人告诉我正确的方式来获得我想要的结果呢?
这里是使用XSLT样式表2.0 for-each-group
在一个递归函数(I更喜欢用XSLT 2.0命名模板):
<xsl:stylesheet version="2.0" 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">
<xsl:param name="prefix" as="xs:string" select="'h'"/>
<xsl:param name="suffix" as="xs:string" select="'-title'"/>
<xsl:output method="html" version="4.0" indent="yes"/>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="items" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$items" group-starting-with="p[@name = concat($prefix, $level, $suffix)]">
<xsl:choose>
<xsl:when test="not(self::p[@name = concat($prefix, $level, $suffix)])">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="h{$level}">
<xsl:apply-templates select="."/>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:element>
</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="body">
<xsl:copy>
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当我申请的是样式与撒克逊9的输入
<body>
<p name="h-title" other="main">Introduction</p>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<p name="h2-title" other=" other-h2">XSLT</p>
<p name="">
<p1 name="bold"> XSLT is used to write stylesheets.</p1>
</p>
<p name="h2-title" other="other-h2">XQuery</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h3-title" other="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<p name="h2-title" other=" other-h2">XSLT</p>
</body>
我得到的结果
<body>
<p name="h-title" other="main">Introduction</p>
<h1>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<h2>
<p name="h2-title" other=" other-h2">XSLT</p>
<p name="">
<p1 name="bold"> XSLT is used to write stylesheets.</p1>
</p>
</h2>
<h2>
<p name="h2-title" other="other-h2">XQuery</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<h3>
<p name="h3-title" other="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
</h3>
</h2>
</h1>
<h1>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<h2>
<p name="h2-title" other=" other-h2">XSLT</p>
</h2>
</h1>
</body>
这种变换键和处理h1-title
到h6-title
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="body">
<xsl:apply-templates select="p[@name='h1-title']" />
</xsl:template>
<xsl:key name="next-headings" match="p[@name='h6-title']"
use="generate-id(preceding-sibling::p
[ @name='h1-title'
or @name='h2-title'
or @name='h3-title'
or @name='h4-title'
or @name='h5-title'
][1])" />
<xsl:key name="next-headings" match="p[@name='h5-title']"
use="generate-id(preceding-sibling::p
[ @name='h1-title'
or @name='h2-title'
or @name='h3-title'
or @name='h4-title'
][1])" />
<xsl:key name="next-headings" match="p[@name='h4-title']"
use="generate-id(preceding-sibling::p
[ @name='h1-title'
or @name='h2-title'
or @name='h3-title'
][1])" />
<xsl:key name="next-headings" match="p[@name='h3-title']"
use="generate-id(preceding-sibling::p
[ @name='h1-title'
or @name='h2-title'
][1])" />
<xsl:key name="next-headings" match="p[@name='h2-title']"
use="generate-id(preceding-sibling::p
[@name='h1-title'][1])" />
<xsl:key name="immediate-nodes" match=
"node()[not(self::p)
or
not(contains('|h1-title|h2-title|h3-title|h4-title|h5-title|h6-title|',
concat('|',@name,'|')
)
)]"
use="generate-id(preceding-sibling::p
[contains('|h1-title|h2-title|h3-title|h4-title|h5-title|h6-title|',
concat('|',@name,'|')
)
][1])" />
<xsl:template match=
"p[contains('|h1-title|h2-title|h3-title|h4-title|h5-title|h6-title|',
concat('|',@name,'|')
)]">
<xsl:variable name="vLevel" select="substring(@name,2,1)" />
<xsl:element name="h{$vLevel}">
<xsl:copy-of select="."/>
<xsl:apply-templates select="key('immediate-nodes', generate-id())" />
<xsl:apply-templates select="key('next-headings', generate-id())" />
</xsl:element>
</xsl:template>
<xsl:template match="/*/node()" priority="-20">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
当该XML文档上施加 (校正为所提供的一个和全光照均匀值name
属性):
<body>
<p name="h1-title" other="main">Introduction</p>
<p name="h2-title" other="other-h2">XSLT and XQuery</p>
<p name="h3-title" other=" other-h3">XSLT</p>
<p name="">
<p1 name="bold"> XSLT is used to write stylesheets.</p1>
</p>
<p name="h2-title" other="other-h2">XQuery</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h3-title" other="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<p name="h2-title" other=" other-h2">XSLT</p>
</body>
在想,正确的结果产生 :
<h1>
<p name="h1-title" other="main">Introduction</p>
<h2>
<p name="h2-title" other="other-h2">XSLT and XQuery</p>
<h3>
<p name="h3-title" other=" other-h3">XSLT</p>
<p name="">
<p1 name="bold"> XSLT is used to write stylesheets.</p1>
</p>
</h3>
</h2>
<h2>
<p name="h2-title" other="other-h2">XQuery</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
<h3>
<p name="h3-title" other="other-h3">XQuery and stylesheets</p>
<p name="">
<p1 name="bold"> XQuery is used to query XML databases.</p1>
</p>
</h3>
</h2>
</h1>
<h1>
<p name="h1-title" other="other-h1">XSLT and XQuery</p>
<h2>
<p name="h2-title" other=" other-h2">XSLT</p>
</h2>
</h1>
请注意 :
这种转变解决了产生层级的主要问题 。 如果需要的是顶层只需要一些简单的改变name
属性的值为"h-title"
。
如果有更多的层级是必要的,这个只需要机械添加相应的or
条款,按键的定义,并附加所有的管道分隔字符串name
属性的值与相应的新的字符串。
在这里,我已经适应并重新使用的杰尼·坦尼森了一个类似的问题的解决方案。
您的每个分组的步骤走的是原始的元素集合作为输入的,而你需要每个步骤由前面的分组步骤产生的团体合作。 还有很多其他的错误太多,例如H1-标题不是属性名称。
它需要是这样的:
<xsl:for-each-group select="*" group-starting-with="*[@name='h1-title']">
<h1>
<xsl:choose>
<xsl:when test="@name='h1-title'">
<xsl:for-each-group select="current-group()" group-starting-with="*[name='h2-title']">
<xsl:choose>
<h2>
... similar logic for the next level ...
</h2>
</xsl:choose>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</h1>
</xsl:for-each-group>
你可以在尽可能深,你根据你想要多少级处理想窝; 或者,如果你想处理一个不确定的数字,你可以把代码命名模板并进行递归调用来处理一个新的水平。 在最里面的级别,离开了xsl:choose
和刚做xsl:copy-of select="current-group()
(我只注意到了尾随空格在“名称”属性。如果这些真的存在,则需要将它们包括在对比测试,或做normalize-space()
摆脱他们的。)