XSLT转换传递参数

3

我正在尝试在XSLT转换期间传递参数。以下是xsl样式表。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:param name="param1" select="'defaultval1'" />
 <xsl:param name="param2" select="'defaultval2'" /> 
 <xsl:template match="/">
  <xslttest>
    <tagg param1="{$param1}"><xsl:value-of select="$param2" /></tagg>
  </xslttest>
</xsl:template>
</xsl:stylesheet>

以下是Java代码中的部分内容。

File xsltFile = new File("template.xsl");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document stylesheet = builder.parse("template.xsl");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer xsltTransformer = transformerFactory.newTransformer(new DOMSource(stylesheet));
//Transformer xsltTransformer = transformerFactory.newTransformer(new StreamSource(xsltFile));
xsltTransformer.setParameter("param1", "value1");
xsltTransformer.setParameter("param2", "value2");
StreamResult result = new StreamResult(System.out);
xsltTransformer.transform(new DOMSource(builder.newDocument()), result);

我遇到了以下错误: ERROR: '变量或参数'param1'未定义。' FATAL ERROR: '无法编译样式表'
然而,如果我使用下面的代码创建转换器,一切都正常。
Transformer xsltTransformer = transformerFactory.newTransformer(new StreamSource(xsltFile));

问题1:我只是想知道在创建Transformer时使用DOMSource有什么问题。

问题2:这是否是替换XML文档中占位符值的理想方式之一?如果我的占位符在源XML文档中,是否有任何(简单明了的)方法可以使用样式表进行替换(并传递参数)?


这里有关于使用DOMSource的其他问题,请访问此链接:http://stackoverflow.com/questions/12174297/jaxp-transformer-via-domsource-returns-stylesheet - StuartLC
我认为这是一个错误,你应该向Oracle报告。JRE使用重新打包的Apache Xalan版本。自2007年以来,那里什么都没有发生过。 - Ingo Kegel
1个回答

2

问题1:这是一个命名空间感知的问题。您需要使DocumentBuilderFactory具有命名空间感知能力:

factory.setNamespaceAware(true);

Q2: 从外部xml文件中获取值有几种方法。其中一种方法是使用文档函数和文档中的顶级变量:

<!-- Loads a map relative to the template. -->
<xsl:variable name="map" select="document('map.xml')"/>

那么您可以从映射中选择值。例如,如果map.xml如下定义:

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
  <mapping key="value1">value2</mapping>
</mappings>

您可以从模板中删除第二个参数,然后使用以下代码查找该值:
<tagg param1="{$param1}"><xsl:value-of select="$map/mappings/mapping[@key=$param1]"/></tagg>

请注意,使用相对文档URI将需要指定样式表的系统ID,因此您需要更新创建DOMSource的方式:

DOMSource source = new DOMSource();
source.setNode(stylesheet);
source.setSystemId(xsltFile.toURL().toString());

一般而言,我建议查看Java的XML API中所有可用的选项。假设所有可用功能都与您要执行的任务不符。我还建议阅读XML信息集。该规范将为您提供API作者使用的所有定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接