XSLT:跨多个文档创建“密钥"? [英] XSLT: create 'key' across multiple documents?

查看:26
本文介绍了XSLT:跨多个文档创建“密钥"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

无论如何都可以使用引用多个 xml 文档的密钥".

Is there anyway to use a 'key' that references multiple xml documents.

类似于:

<xsl:key name="ChildByFIdAndMFId" 
    match="collection('file:///c:/temp/xslt?select=test*.xml')Child"
    use="concat(FathersID, '+', MothersFatherID)"/>

这会产生错误在模式的头部不允许使用集合函数".我试图在多个文档中通过FathersID 和MothersFatherID 引用所有匹配的子"节点,以获得一些统计结果,如总和和计数.能够在 key 语句中使用集合看起来是一个很好的竞争者,但要么我语法错误,要么根本不可能?

That gives an error "The collection function is not allowed at the head of a pattern". I'm trying to reference all the matching 'child' nodes by FathersID and MothersFatherID across multiple documents to get some statistical results like sum's and counts. Being able to use a collection in the key statement looked like a good contender but either I have syntax wrong or maybe that is not possible at all?

详细说明(基于之前的xml和代码)...

To elaborate (based on previous xml and code)...

XML 文件如下所示:

XML files look like:

<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 个节点) - 之间很可能有重复的子节点文件,尽管统计数据(总计)会有所不同.

There may be up to 30 of these files to reference, but I'm only interested in matching Child nodes for now (of which may be in the order of 3000 nodes per file) - there may well be duplicate Child nodes between files although the stats (Total) will be different.

到目前为止的xslt:

The xslt so far:

    <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 给出:

So this works for a single xml document - above xml gives:

    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 的子节点匹配的所有其他文档?

But, if I can't use a collection in the key, how do I go about referencing all the other documents matching the child nodes for the current FatherID and MothersFatherID?

例如,如果将上述 xml 复制到另外两个需要从中提取数据的文件,则输出将具有新的总和,例如:

If, for example, the above xml was duplicated as is to two more files that need the data pulled from them the output would have new Sum of Total like:

    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

我可以看到我想使用集合",以便我可以轻松地提取所有文件,但我看不到在哪里或如何提取.有人可以帮我吗?

I can see I would like to use a 'collection' so I can easily pull in all the files, but I can't see where or how. Can anyone help me please?

推荐答案

正如 Dimitre 所说,key() 只搜索一个文档.如果您想搜索一组文档,这很容易:使用 $s/key(...) 其中 $s 保存一组文档.可以从对 collection() 函数的调用、从提供一组 URI 的对 document() 的调用或通过组合对 doc() 的多次调用的结果获得一组文档,例如 对于 $uri-list 中的 $x 返回 doc($x).

As Dimitre says, key() only searches one document. If you want to search a set of documents, it's easy enough: use $s/key(...) where $s holds the set of documents. A set of documents might be obtained from a call to the collection() function, from a call to document() supplying a set of URIs, or by combining the result of a number of calls to doc(), for example for $x in $uri-list return doc($x).

这篇关于XSLT:跨多个文档创建“密钥"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆