在尝试创建对外部xml文件的交叉引用以用xslt替换原始xml中的值时,我遇到了一个问题,没有返回任何内容。
标题为"codes.xml"的外部文档
<?xml version="1.0" encoding="utf-8"?>
<codes>
<paymentmethodcode>
<code id="CHK" desc="Check"/>
<code id="ACH" desc="Automated Clearing House" />
<code id="BOP" desc="Financial Institution Option" />
<code id="FWT" desc="Federal Reserve Funds" />
<code id="NON" desc="Non Payment Data" />
</paymentmethodcode>
</codes>
这是样式表的顶部:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="lookup" select="'codes.xml'" />
<xsl:variable name="lookupDoc" select="document($lookup)" />
<xsl:key name='paymentmethodcode' match='lu:codes/paymentmethodcode/code' use='@id' />
在模板中,我尝试检索代码的'desc'属性,但是在应用"normalize-space()"函数之前什么也没有返回:
<xsl:template match ="FunctionGroup/Transaction">
<div class="infoLeft">
<p><label>Filename:</label></p>
<p><label>Pay Method:</label>
<xsl:variable name="paymethodvalue" select="normalize-space(BPR/BPR04)" />
<xsl:for-each select="$lookupDoc">
<xsl:variable name="value" select="key('paymentmethodcode', $paymethodvalue)" />
<xsl:value-of select="$value/@desc"/>
</xsl:for-each></p>
</div>
</xsl:template>
:
<xsl:template match="*">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>EDI</title>
</head>
<body>
<xsl:apply-templates select="FunctionGroup/Transaction" />
</body>
</html>
</xsl:template>
下面是输入文件的最小化版本:
<?xml version="1.0"?>
<FunctionGroup>
<Transaction>
<BPR>
<BPR04>
CHK
</BPR04>
</BPR>
</Transaction>
</FunctionGroup>
我们看不到您的输入XML,所以我们不知道模板是否匹配任何内容。我建议您尝试以下测试样式表(带任何输入):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="lookup" select="'codes.xml'" />
<xsl:variable name="lookupDoc" select="document($lookup)" />
<xsl:key name="paymentmethodcode" match="code" use='@id' />
<xsl:template match="/">
<xsl:for-each select="$lookupDoc">
<result>
<xsl:value-of select="key('paymentmethodcode', 'CHK')/@desc"/>
</result>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
返回;
<?xml version="1.0" encoding="UTF-8"?>
<result>Check</result>
注意,没有必要引用lu:前缀或其关联的名称空间。
编辑:
改变:
<xsl:variable name="paymethodvalue" select="BPR/BPR04" />
:
<xsl:variable name="paymethodvalue" select="normalize-space(BPR/BPR04)" />
或者在调用key()函数时应用normalize-space()函数,即:
<xsl:value-of select="key('paymentmethodcode', normalize-space($paymethodvalue))/@desc"/>
xsl:for-each select="$lookupDoc/paymentmethodcode/code"
根据您的match
看起来是错误的,我认为您只需要xsl:for-each select="$lookupDoc"
将上下文更改为基于key
的查找的外部文档。如果这样的更改还不足以使其工作,那么请向我们展示输入XML、XSLT和查找文档中使用的名称空间的所有细节。
我试着用你的代码片段重现这个问题,XSLT是
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:lu="http://example.com/lookup">
<xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="lookup" select="'test2014081201.xml'" />
<xsl:variable name="lookupDoc" select="document($lookup)" />
<xsl:key name='paymentmethodcode' match='lu:codes/paymentmethodcode/code' use='@id' />
<xsl:template match ="FunctionGroup/Transaction">
<div class="infoLeft">
<p><label>Filename:</label></p>
<p><label>Pay Method:</label>
<xsl:for-each select="$lookupDoc">
<xsl:variable name="value" select="key('paymentmethodcode', 'CHK')" />
<xsl:value-of select="$value/@desc"/>
</xsl:for-each></p>
</div>
</xsl:template>
</xsl:stylesheet>
XML输入只是
<FunctionGroup>
<Transaction>foo</Transaction>
</FunctionGroup>
查找文档是发布的,然后Saxon 6.5给出结果
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<div xmlns:lu="http://example.com/lookup" class="infoLeft">
<p><label>Filename:</label></p>
<p><label>Pay Method:</label>Check
</p>
</div>