用动态值替换XSLT?

时间:2012-12-05 13:37:14

标签: java xml xslt

我有一个xsl模板,可以替换一些xml值。 现在我想通过我的代码动态生成这些值。

Transformer trans = TransformerFactory.newInstance().newTransformer(new StreamSource(new File("foo.xsl"));
trans.transform(new StreamSource(new File("foo.xml"), new StreamResult(new File("output.xml")));

我如何才能实现,例如只更换id = 1的名称?而且还通过javacode动态提供id,而不是硬编码?

<?xml version="1.0"?>
<my:accounts xmlns:my="http://myns">
<my:account>
<my:name>alex</my:name>
<my:id>1</my:id>
</my:account>
<my:account>
<my:name>Fiona</my:name>
<my:id>2</my:id>
</my:account>
</my:accounts>

这取代了所有名称:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://myns">

 <xsl:param name="propertyName" select="'alex'"/>

      <xsl:template match="node() | @*">
        <xsl:copy>
          <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
     </xsl:template>

<xsl:template match="*[local-name()='account']/*[local-name()='name']/text()[.='{$propertyName}']">
       <xsl:text>johndoe</xsl:text>
      </xsl:template>
    </xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="http://myns">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pId" select="2"/>

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
 </xsl:template>

 <xsl:template match="my:name/text()">
   <xsl:choose>
     <xsl:when test="../../my:id = $pId">johndoe</xsl:when>
     <xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<my:accounts xmlns:my="http://myns">
    <my:account>
        <my:name>alex</my:name>
        <my:id>1</my:id>
    </my:account>
    <my:account>
        <my:name>Fiona</my:name>
        <my:id>2</my:id>
    </my:account>
</my:accounts>

生成想要的正确结果

<my:accounts xmlns:my="http://myns">
   <my:account>
      <my:name>alex</my:name>
      <my:id>1</my:id>
   </my:account>
   <my:account>
      <my:name>johndoe</my:name>
      <my:id>2</my:id>
   </my:account>
</my:accounts>

<强>解释

  1. 使用全局范围<xsl:param>。虽然设置了默认值,但它会被转换调用者指定的值覆盖。

  2. 请注意,如何为转换指定外部参数值的问题对于不同的xslt处理器(供应商)有不同的答案。您需要阅读您正在使用的特定XSLT处理器的文档,以获得针对您的特定情况的答案。

答案 1 :(得分:0)

您可以在xsl样式表中定义参数

<xsl:param name="id" select="'0'"/>

然后将其作为Java中的参数传递:

trans.setParameter(&#34; id&#34;,&#34; 1&#34;);

这对你有用吗?或者你想传递多个参数?

类似于提到的内容here - The Transformer Class

此xsl有效,但它在2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://myns">
<xsl:param name="id" select="'1'"/>

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
 </xsl:template>

<xsl:template match="*[local-name()='account'][*:id=$id]/*[local-name()='name']/text()">
   <xsl:text>johndoe</xsl:text>
  </xsl:template>
</xsl:stylesheet>