2

继上一个问题' xslt:通过中间参考节点选择唯一节点?'。

无论如何要使用引用多个 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

我可以看到我想使用“集合”,这样我就可以轻松地提取所有文件,但我看不到在哪里或如何。任何人都可以帮助我吗?

4

1 回答 1

4

正如 Dimitre 所说,key()只搜索一个文档。如果要搜索一组文档,这很简单:使用$s/key(...)$s 保存文档集的位置。一组文档可以通过调用 collection() 函数、通过调用提供一组 URI 的 document() 或通过组合多次调用 doc() 的结果来获得,例如for $x in $uri-list return doc($x).

于 2013-02-08T08:10:23.057 回答