XSLT 和临时文件 [英] XSLT and temporary documents
问题描述
我正在尝试处理一个包含多个不同状态组的 xml 文件,例如
I am trying to process an xml file which has several different state groups like
<root>
<childgroup>16</childgroup>
<setstate>init</setstate>
<child1>...</child1>
<child2>...</child2>
<setstate>process<setstate>
<child2>...</child2>
<child3>...</child3>
.....
<childgroup>17</childgroup>
...
我真正需要的是得到类似的东西<代码>
What I need is actually get something like
<childgroup no="16">
<state statename="init">
<child1>...</child1>
<child2>...</child2>
</state>
<state statename="process">
<child2>...</child2>
<child3>...</child3>
</state>
</childgroup>
<childgroup no="17">
...
我已经完成了简单的部分,将chgrpno"属性和 stateid 属性添加到所有子元素(它复制除子组和状态之外的所有元素,将属性添加到这两个元素.
I've done simple part which is going and adding "chgrpno" attribute and stateid attribute to all childs (it makes copy-of of all elements but childgroup and state, adding the attribute to those two.
<xsl:template match="/">
<xsl:apply-templates mode="numb"/>
</xsl:template>
这有效,结果所有孩子都有属性,所以我可以在下一次通过时重新组合他们,状态有数字,所以我以后可以做同样的事情.但是当我尝试做时,我试图用临时文件"来效仿 M.Kay 的例子
This works and in the result all childs have attribute so I could regroup them in the next pass and states have numbers so I could later make same thing. But trying to follow the example of M.Kay with "temporary documents" when I try to do
<xsl:variable name="nmb">
<xsl:apply-templates mode="numb"/>
</xsl:variable>
<xsl:template match="/">
<xsl:copy-of select="$nmb"/>
</xsl:template>
然后它只是将原件返回给我,而我在第一遍中所做的所有更改都消失了.那么我在这里做错了什么?
then it just returns the original to me, and all changes which I made in the first pass are gone. So what am I doing wrong here?
我明确使用 XSLT 1.0,而不是 XSLT 2.0.
I use XSLT 1.0, not XSLT 2.0 explicitly.
(我当然给变量命名了,忘了在这里复制).
(edit: surely I named the variable, forgot to copy it here).
推荐答案
这里是一个例子,如何一步一步地使用 XSLT 1.0 进行分组;样式表
Here is an example how to approach the grouping with XSLT 1.0 in one step; the stylesheet
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="k1" match="root/*[not(self::childgroup)]"
use="generate-id(preceding-sibling::childgroup[1])"/>
<xsl:key name="k2" match="root/*[not(self::childgroup) and not(self::setstate)]"
use="concat(generate-id(preceding-sibling::childgroup[1]), '|', generate-id(preceding-sibling::setstate[1]))"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="childgroup"/>
</xsl:copy>
</xsl:template>
<xsl:template match="childgroup">
<childgroup no="{.}">
<xsl:apply-templates select="key('k1', generate-id())[self::setstate]"/>
</childgroup>
</xsl:template>
<xsl:template match="setstate">
<state statename="{.}">
<xsl:copy-of select="key('k2', concat(generate-id(preceding-sibling::childgroup[1]), '|', generate-id()))"/>
</state>
</xsl:template>
</xsl:stylesheet>
转换输入样本
<root>
<childgroup>16</childgroup>
<setstate>init</setstate>
<child1>...</child1>
<child2>...</child2>
<setstate>process</setstate>
<child2>...</child2>
<child3>...</child3>
<childgroup>17</childgroup>
<setstate>init</setstate>
<child1>...</child1>
<child2>...</child2>
<setstate>process</setstate>
<child2>...</child2>
<child3>...</child3>
</root>
进入
<root>
<childgroup no="16">
<state statename="init">
<child1>...</child1>
<child2>...</child2>
</state>
<state statename="process">
<child2>...</child2>
<child3>...</child3>
</state>
</childgroup>
<childgroup no="17">
<state statename="init">
<child1>...</child1>
<child2>...</child2>
</state>
<state statename="process">
<child2>...</child2>
<child3>...</child3>
</state>
</childgroup>
</root>
这篇关于XSLT 和临时文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!