2012-12-05 58 views
1

我有一個可以替換一些xml值的xsl模板。 現在我想要這些值由我的代碼動態生成。帶動態值的XSLT替換?

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

這種轉變

<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處理器的文檔,才能針對您的特定情況獲取此答案。

+0

真的是一個很好的例子,它的工作原理。但是如果我將id改爲一個字符串,假設' test'和''這不起作用。我在這裏錯過了什麼? – membersound

+0

好吧,我的壞。使用'<... select =''test'「/>' – membersound

+0

@membersound,不客氣。是的,你必須指定一個字符串文字,否則它被解釋爲節點名稱。 –

0

你可以在你的XSL樣式表定義參數

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

然後將它作爲Java中的參數:

反式.setParameter(「id」,「1」);

這樣可以嗎?或者你想傳遞多個參數?

喜歡的東西是什麼refered 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> 
+0

嗯我嘗試但它不起作用,請參閱上面的更新語句。 – membersound

+0

Try @Dimitre Novatchev's似乎可行,它符合1.0規範 –