我正在尝试使用Saxon 9.1.0.7进行简单的外部查找.
我有一个简单的源文件dummy.xml:
<something>
<monkey>
<genrecode>AAA</genrecode>
</monkey>
<monkey>
<genrecode>BBB</genrecode>
</monkey>
<monkey>
<genrecode>ZZZ</genrecode>
</monkey>
<monkey>
<genrecode>ZER</genrecode>
</monkey>
</something>
Run Code Online (Sandbox Code Playgroud)
然后查找文件是GenreSet_124.xml:
<GetGenreMappingObjectsResponse>
<tuple>
<old>
<GenreMapping DepartmentCode="AAA"
DepartmentName="AND - NEWS AND CURRENT AFFAIRS"
Genre="10 - NEWS"/>
</old>
</tuple>
<tuple>
<old>
<GenreMapping DepartmentCode="BBB"
DepartmentName="AND - NEWS AND CURRENT AFFAIRS"
Genre="11 - NEWS"/>
</old>
</tuple>
... lots more
</GetGenreMappingObjectsResponse>
Run Code Online (Sandbox Code Playgroud)
我想要实现的只是获取基于"DepartmentCode"值的"类型"值.
所以我的XSL看起来像:
...
<!-- Set up the genre lookup key -->
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/>
<xsl:variable name="lookupDoc" select="document('GenreSet_124.xml')"/>
<xsl:template match="/something">
<stuff>
<xsl:for-each select="monkey">
<Genre>
<xsl:apply-templates select="$lookupDoc">
<xsl:with-param name="curr-label" select="genrecode"/>
</xsl:apply-templates>
</Genre>
</xsl:for-each>
</stuff>
</xsl:template>
<xsl:template match="GetGenreMappingObjectsResponse">
<xsl:param name="curr-genrecode"/>
<xsl:value-of select="key('genre-lookup', $curr-genrecode)/@Genre"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
...
我遇到的问题是我得不到任何回报.我目前刚刚得到
<?xml version="1.0" encoding="UTF-8"?>
<stuff>
<Genre/>
<Genre/>
<Genre/>
<Genre/>
</stuff>
Run Code Online (Sandbox Code Playgroud)
我已将所有查找数据移动为GenreMapping的属性,以前作为GenreMapping的子元素,每当我输入模板match ="GetGenreMappingObjectsResponse"时,它只会打印出每个GenreMapping(DepartmentCode,DepartmentName,Genre)中的所有文本!
我不能为我的生活弄清楚我做错了什么.任何帮助/建议将不胜感激.
请找到当前的实际XSLT列表:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Define the global parameters -->
<xsl:param name="TransformationID"/>
<xsl:param name="TransformationType"/>
<!-- Specify that XML is the desired output type -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<!-- Set up the genre matching capability -->
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/>
<xsl:variable name="documentPath"><xsl:value-of select="concat('GenreSet_',$TransformationID,'.xml')"/></xsl:variable>
<xsl:variable name="lookupDoc" select="document($documentPath)"/>
<!-- Start the first match on the Root level -->
<xsl:template match="/something">
<stuff>
<xsl:for-each select="monkey">
<Genre>
<xsl:apply-templates select="$lookupDoc/*">
<xsl:with-param name="curr-genrecode" select="string(genrecode)"/>
</xsl:apply-templates>
</Genre>
</xsl:for-each>
</stuff>
</xsl:template >
<xsl:template match="GetGenreMappingObjectsResponse">
<xsl:param name="curr-genrecode"/>
<xsl:value-of select="key('genre-lookup', $curr-genrecode, $lookupDoc)/@Genre"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
TransformationID总是124(因此打开了正确的查找文件.类型只是我目前没有使用但打算使用的名称.
在XSLT 2.0中,有两种方法可以执行您想要的操作:
一个是key函数的三参数版本.第三个参数允许您指定希望密钥处理的根节点(默认情况下,它始终是主文档的根):
<xsl:value-of select="key('genre-lookup', $curr-genrecode,$lookupDoc)/@Genre"/>
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用节点key下的函数$lookupDoc:
<xsl:value-of select="$lookupDoc/key('genre-lookup', $curr-genrecode)/@Genre"/>
Run Code Online (Sandbox Code Playgroud)
这两种方法都记录在密钥的XSLT 2.0规范中,并且在XSLT 1.0中不起作用.
为了完整起见,如果您仅限于XSLT 1.0,则必须重写此操作以不使用密钥.
<xsl:value-of select="$lookupDoc//GenreMapping[@DepartmentCode = $curr-genrecode]/@Genre"/>
Run Code Online (Sandbox Code Playgroud)
啊哈!问题是select="$lookupDoc"您的apply-templates调用是调用默认模板而不是您期望的模板,因此参数会丢失.
把它改成这个:
<xsl:apply-templates select="$lookupDoc/*">
<xsl:with-param name="curr-genrecode" select="string(genrecode)"/>
</xsl:apply-templates>
Run Code Online (Sandbox Code Playgroud)
这将正确调用您的模板,密钥应该可以正常工作.
所以最终的XSLT表看起来应该是这样的:
<xsl:variable name="lookupDoc" select="document('XMLFile2.xml')"/>
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/>
<xsl:template match="/something">
<stuff>
<xsl:for-each select="monkey">
<Genre>
<xsl:apply-templates select="$lookupDoc/*">
<xsl:with-param name="curr-genrecode" select="string(genrecode)"/>
</xsl:apply-templates>
</Genre>
</xsl:for-each>
</stuff>
</xsl:template>
<xsl:template match="GetGenreMappingObjectsResponse">
<xsl:param name="curr-genrecode"/>
<xsl:value-of select="key('genre-lookup',$curr-genrecode,$lookupDoc)/@Genre"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
(信息来源)