我有以下XML:
<?xml version="1.0"?>
<abc:Element1 xmlns:abc="http://..../resources/abc/v2/"
...>
<abc:Element2>
<abc:Element3s>
<abc:Element4 name="name1"
resourceRef="name2"/>
</abc:Element3s>
</abc:Element2>
<abc:Resources>
<abc:Resource xsi:type="abc:Something"
name="name2"/>
</abc:Resources>
</abc:Element1>
...和这个XSLT样式表:
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:abc="http://.../resources/abc/v2/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<checker name="something">
<xsl:for-each select="abc:Element1/abc:Element2/abc:Element3s/abc:Element4">
<xsl:variable name="resource" select="@resourceRef"/>
<xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>
<xsl:choose>
<xsl:when test="$xsiType='abc:Something'">
...
</xsl:when>
<xsl:otherwise>
...
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</checker>
</xsl:template>
</xsl:stylesheet>
我正在使用XALAN 2.7.1和org.apache.xalan.xsltc.trax.TransformerFactoryImpl(也尝试使用org.apache.xalan.processor.TransformerFactoryImpl - &gt;相同的结果)来转换XML。
我希望以下行在变量 xsiType 中存储 abc:Something 。
<xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>
但不幸的是只有 Something (没有名称空间作为前缀)存储在 xsiType 中。我验证了这一点,因为
<xsl:when test="$xsiType='abc:Something'">
不是真的。
我还使用 xsltproc 转换了XMl,结果XML看起来像预期的那样。因此,我希望输入XML / XSLT样式表是正确的。我假设Xalan及其配置有问题。
有人可以帮忙吗?
答案 0 :(得分:1)
您的样本数据格式不正确,因此很难说清楚。这可能是命名空间问题。这是输入和样式表的清理版本,用于提取所需的数据:
<?xml version="1.0"?>
<abc:Element1
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:abc="http://resources/abc/v2">
<abc:Element2>
<abc:Element3s>
<abc:Element4 name="name1" resourceRef="name2"/>
</abc:Element3s>
</abc:Element2>
<abc:Resources>
<abc:Resource xsi:type="abc:Something" name="name2"/>
</abc:Resources>
</abc:Element1>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:abc="http://resources/abc/v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="abc xsi"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="resource" select="'name2'"/>
<xsl:variable name="type"
select="//abc:Resource[@name=$resource]/@xsi:type"/>
<checker name="{ $type }"/>
</xsl:template>
</xsl:stylesheet>
这将产生:
<?xml version="1.0"?>
<checker name="abc:Something"/>
答案 1 :(得分:1)
在我看来,这是一个特定于Xalan的问题。然而,它可能是底层XML解析器的问题:Sun JDK中的默认解析器有一些奇怪的错误,包括一些破坏属性值的错误。始终使用Apache版本的Xalan和Xerces而不是JDK附带的版本。当然,如果您使用的是Xalan,那么切换到Saxon的成本几乎为零,这将为您提供XSLT 2.0的所有优势。