从外部 xml 文件中查找 XSLT [英] XSLT lookup from external xml file

查看:23
本文介绍了从外部 xml 文件中查找 XSLT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这里有很多关于通过 xslt 从外部 xml 文件中查找的问题(和答案).但是,我仍然没有弄清楚关键函数的逻辑,所以我很难将其他解决方案应用到我的用例中.

我有两个 xml 文件:

versA.xml

<div><l id="A001" corresp="B001">VersA的第一行</l><l id="A002" corresp="B002">VersA的第二行</l><l id="A003" corresp="B003">VersA的第三行</l>

</TEI>

versB.xml

<div><l id="B001" corresp="A001">VersB的第一行</l><l id="B002" corresp="A002">VersB的第二行</l><l id="B003" corresp="A003">VersB的第三行</l>

</TEI>

文件通过 corresp 属性相互引用.

我正在尝试找出一个 xsl 样式表 (trans.xsl) 来解析 versA.xml,打印自己的文本节点,然后查找相应的文本versB.xml

中的节点

trans.xsl

<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/><xsl:variable name="vB" select="document('versB.xml')/TEI/div/l"/><xsl:template match="/TEI/div/l">我找到了 ID <xsl:value-of select="@id"/>在 versA.xml 中.如何在 versB.xml 中获取 ID 为  的相应节点?</xsl:模板></xsl:stylesheet>

我能做的是输出versA.xml的id并访问versB.xml.然而,我发现设置一个合适的键函数来获取 versA.xml 中的 corresp 值来在 versB.xml 中查找相应的 id 非常困难

如果有人能解释如何实现这一点,我会很高兴.

出于兼容性原因,首选 xslt 1.0 版.

我已经根据评论中给出的建议更新了我的样式表.以下给出了所需的输出:

<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/><xsl:key name="ref" match="TEI/div/l" use="@id"/><xsl:template match="/TEI/div/l"><xsl:variable name="corresp" select="@corresp"/><xsl:value-of select="."/>对应于<xsl:for-each select="document('versB.xml')"><xsl:value-of select="key('ref', $corresp)"/></xsl:for-each></xsl:模板></xsl:stylesheet>

解决方案

你需要用 xsl:key 声明一个键,给它一个 name 你可以选择,使用要索引"的节点的 match 模式,要为其声明键,并使用 use 属性定义键值,XPath 表达式:

要使用键,请调用 key 函数,其中声明的键的名称作为第一个参数,键值作为第二个参数,在 XSLT 2 或更高版本中,文档或子树你想搜索,作为第三个参数:key('ref', @corresp, document('versB.xml')).

如果你真的被限制在 XSLT 1 那么,对于两个不同的文档,由于 key 函数的第三个参数不被支持,你需要用 切换上下文文档"for-each,例如:

<xsl:variable name="corresp" select="@corresp"/><!-- 现在我们更改上下文文档,以便能够在辅助输入上应用键函数--><xsl:for-each select="document('versB.xml')"><xsl:value-of select="key('ref', $corresp)"/></xsl:for-each>

上述 key 函数的两个示例使用都假定您在 xsl:template match="/TEI/div/l" 的上下文中创建它们,以便 @corresp 选择主输入中 l 元素的该属性的值.

I am aware that there are plenty of questions (and answers) here on the lookup from external xml files via xslt. However, I still haven't got my head around the logic of the key function so I'm having a hard time applying other solutions to my use case.

I have two xml files:

versA.xml

<TEI>
  <div>
    <l id="A001" corresp="B001">First line of VersA</l>
    <l id="A002" corresp="B002">Second line of VersA</l>
    <l id="A003" corresp="B003">Third line of VersA</l>
  </div>
</TEI>

and

versB.xml

<TEI>
  <div>
    <l id="B001" corresp="A001">First line of VersB</l>
    <l id="B002" corresp="A002">Second line of VersB</l>
    <l id="B003" corresp="A003">Third line of VersB</l>
  </div>
</TEI>

The files refer to each other via the corresp-attribute.

I'm trying to figure out a xsl stylesheet (trans.xsl) that parses versA.xml, prints its own text node and then looks up the corresponding text node in versB.xml

trans.xsl

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:variable name="vB" select="document('versB.xml')/TEI/div/l"/>

<xsl:template match="/TEI/div/l">
I found ID <xsl:value-of select="@id"/> in versA.xml.
How can I get the corresponding node in versB.xml which has the ID <xsl:value-of select="@corresp"/>?
</xsl:template>


</xsl:stylesheet>

What I can do is output the ids of versA.xml and access versB.xml. I find it extremely difficult however, to set up an appropriate key function that takes the corresp value from versA.xml to look up the corresponding id in versB.xml

I'd be happy if somebody could explain how this can be achieved.

For compatibility reasons xslt version 1.0 would be preferred.

I have updated my stylesheet according to the suggestions given in the comments. The following gives the desired output:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="ref" match="TEI/div/l" use="@id"/>

<xsl:template match="/TEI/div/l">

  <xsl:variable name="corresp" select="@corresp"/>
  <xsl:value-of select="."/> corresponds to 
  <xsl:for-each select="document('versB.xml')">
     <xsl:value-of select="key('ref', $corresp)"/>
   </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

解决方案

You need to declare a key with xsl:key, giving it a name you can choose, using a match pattern of the nodes you want to "index", you want to declare the key for, and defining a key value with the use attribute, an XPath expression:

<xsl:key name="ref" match="TEI/div/l" use="@id"/>

To use a key you call the key function with the name of the declared key as the first argument, the key value as the second argument and, in XSLT 2 or later, the document or subtree you want to search, as the third argument: key('ref', @corresp, document('versB.xml')).

If you are really restricted to XSLT 1 then, with two different documents, as the third argument of the key function is not supported, you need to switch the "context document" with for-each, for instance:

<!-- need to store value of main input document we want to lookup in variable -->
<xsl:variable name="corresp" select="@corresp"/>

<!-- now we change the context document to be able to apply the key function on secondary input -->
<xsl:for-each select="document('versB.xml')">
   <xsl:value-of select="key('ref', $corresp)"/>
</xsl:for-each>

Both example uses of the key function above assume you make them in the context of an xsl:template match="/TEI/div/l" so that @corresp selects the value of that attribute of an l element in your main input.

这篇关于从外部 xml 文件中查找 XSLT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆