【发布时间】:2013-01-23 15:41:22
【问题描述】:
继上一个问题“xslt: select unique node via intermediate reference node?”之后。
是否可以使用引用多个 xml 文档的“键”。
类似:
<xsl:key name="ChildByFIdAndMFId"
match="collection('file:///c:/temp/xslt?select=test*.xml')Child"
use="concat(FathersID, '+', MothersFatherID)"/>
这给出了一个错误“模式的头部不允许收集函数”。 我试图在多个文档中通过 FathersID 和 MothersFatherID 引用所有匹配的“子”节点,以获得一些统计结果,如总和和计数。能够在 key 语句中使用集合看起来是一个很好的竞争者,但要么我的语法错误,要么根本不可能?
详述(基于之前的xml和代码)...
XML 文件如下所示:
<t>
<Children>
<Child>
<ID>1</ID>
<FathersID>100</FathersID>
<MothersFatherID>200</MothersFatherID>
<Total>2</Total>
</Child>
<Child>
<ID>2</ID>
<FathersID>100</FathersID>
<MothersFatherID>201</MothersFatherID>
<Total>3</Total>
</Child>
<Child>
<ID>3</ID>
<FathersID>100</FathersID>
<MothersFatherID>202</MothersFatherID>
<Total>5</Total>
</Child>
<Child>
<ID>4</ID>
<FathersID>100</FathersID>
<MothersFatherID>201</MothersFatherID>
<Total>3</Total>
</Child>
<Child>
<ID>5</ID>
<FathersID>101</FathersID>
<MothersFatherID>201</MothersFatherID>
<Total>4</Total>
</Child>
</Children>
<Fathers>
<Father>
<ID>100</ID>
</Father>
<Father>
<ID>101</ID>
</Father>
</Fathers>
<MothersFathers>
<MothersFather>
<ID>200</ID>
</MothersFather>
<MothersFather>
<ID>201</ID>
</MothersFather>
<MothersFather>
<ID>202</ID>
</MothersFather>
</MothersFathers>
</t>
可能有多达 30 个这些文件可供参考,但我现在只对匹配子节点感兴趣(其中每个文件可能有 3000 个节点) - 之间很可能有重复的子节点文件,尽管统计数据(总计)会有所不同。
到目前为止的 xslt:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kMFByFId" match="MothersFatherID" use="../FathersID"/>
<!--use="../FathersID"/>-->
<xsl:key name="kMFById" match="MothersFather" use="ID"/>
<xsl:key name="ChildByFIdAndMFId" match="Child"
use="concat(FathersID, '+', MothersFatherID)"/>
<xsl:template match="Children|MothersFathers|text()"/>
<xsl:template match="Father">
Father ID=<xsl:value-of select="ID"/>
<xsl:variable name="Fid" select="ID"></xsl:variable>
<xsl:apply-templates select=
"key('kMFById',
key('kMFByFId', ID)
[generate-id(..)
=
generate-id(key('ChildByFIdAndMFId',
concat(../FathersID,'+',.)
)[1]
)
]
)">
<xsl:sort select="ID" data-type="text"/>
<xsl:with-param name="Fid" select="$Fid"></xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="MothersFather">
<xsl:param name="Fid"></xsl:param>
<xsl:variable name="FidAndMid" select="concat($Fid,'+',ID)"></xsl:variable>
MothersFather ID=<xsl:value-of select="ID"/>
Sum of Total= <xsl:value-of
select="sum(key('ChildByFIdAndMFId', $FidAndMid)/Total)"/>
</xsl:template>
</xsl:stylesheet>
所以这适用于单个 xml 文档 - 上面的 xml 给出:
Father ID=100
MothersFather ID=200
Sum of Total= 2
MothersFather ID=201
Sum of Total= 6
MothersFather ID=202
Sum of Total= 5
Father ID=101
MothersFather ID=201
Sum of Total= 4
但是,如果我不能在键中使用集合,我该如何引用与当前父亲 ID 和母亲父亲 ID 的子节点匹配的所有其他文档?
例如,如果上述 xml 被复制到另外两个需要从中提取数据的文件中,则输出将具有新的总和,例如:
Father ID=100
MothersFather ID=200
Sum of Total= 6
MothersFather ID=201
Sum of Total= 18
MothersFather ID=202
Sum of Total= 15
Father ID=101
MothersFather ID=201
Sum of Total= 12
我可以看到我想使用“集合”,这样我就可以轻松地提取所有文件,但我看不出在哪里或如何。谁能帮帮我?
【问题讨论】:
-
关于语法,我会在集合函数和子元素之间添加一个斜线:
match="collection('file:///c:/temp/xslt?select=test*.xml')/Child"。但我很怀疑即使解决了这个问题也会起作用。 -
嗨 Lars,我已经尝试过了,但仍然给出了同样的错误
The collection("file:///c:/temp/xslt?select=test*.xml") function is not allowed at the head of a pattern。干杯... -
一个键一次只索引一个文档。如果您想跨多个文件进行分组,请使用:
<xsl:for-each-group select="yourSequenceFromMultipleDocuments"> -
谢谢 Dimitre,我现在就来看看如何使用 'for-each-group' 看看我的进展如何......
-
嗨,Dimitre,在我的情况下,我在为每个组进行锻炼时遇到了麻烦,然后看到了我喜欢的 Michaels 的回答。干杯,布莱斯。