XSLT:创建'密钥'跨多个文件?

时间:2013-02-07 23:20:17

标签: xslt xslt-2.0

来自上一个问题“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在多个文档中引用所有匹配的“子”节点,以获得一些统计结果,如sum和count。能够在关键语句中使用集合看起来像是一个很好的竞争者,但要么我的语法错误,要么根本不可能?

详细说明(基于以前的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个要引用,但我现在只对匹配的Child节点感兴趣(其中每个文件可能大约有3000个节点) - 两者之间可能存在重复的Child节点文件虽然统计(总计)会有所不同。

到目前为止的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

但是,如果我不能在密钥中使用集合,我该如何引用与当前FatherID和MothersFatherID的子节点匹配的所有其他文档?

例如,如果上面的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

我可以看到我想使用'收藏',所以我可以轻松拉入所有文件,但我看不到在哪里或如何。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:3)

正如Dimitre所说,key()只搜索一个文档。如果要搜索一组文档,这很容易:使用$s/key(...),其中$ s包含文档集。可以从对collection()函数的调用,从提供一组URI的document()的调用,或者通过将多个调用的结果组合到doc()中获得一组文档,例如{{1 }}