2013-03-02 60 views
2

我以下的問題看的代碼示例:要創建什麼?一個函數或模板還是?

<xsl:if test="/Document/test/id"> 
    <TEST1> 
    <xsl:value-of select="/Document/test/id"/> 
    </TEST1> 
</xsl:if> 

我有一個巨大的XSLT腳本用了很多相同的代碼。我想創建一個函數,但我得到了所有的時間錯誤。我問自己,如果這是解決這個問題的正確解決方案。

爲了使代碼更好地維護,我想使用類似下面的內容。 這不是xslt的語法,因爲我不知道如何,但給一個想法,我在找什麼。

... 
<xsl:something "TEST1", "/Document/test/id1" /> 
<xsl:something "TEST2", "/Document/test/id2" /> 
... 

的代碼將是更好的可讀性和可維護性,雖然我不知道如何解決這個:-( 任何建議,歡迎...

問候德克

回答

2

這種轉變

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my:my" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:variable name="vDoc" select="/"/> 

<xsl:template match="/"> 
    <xsl:sequence select="my:test(xs:QName('Test1'), /*/test/id1/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test2'), /*/test/id2/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test3'), /*/test/id3/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test4'), /*/test/id4/string())"/> 
</xsl:template> 

<xsl:function name="my:test"> 
    <xsl:param name="pName" as="xs:QName"/> 
    <xsl:param name="pToPresent" as="item()?"/> 

    <xsl:if test="$pToPresent"> 
    <xsl:element name="{$pName}"> 
      <xsl:sequence select="$pToPresent"/> 
    </xsl:element> 
    </xsl:if> 
</xsl:function> 
</xsl:stylesheet> 

當在下面的XML文檔應用:

<Document> 
<test> 
    <id1>Some Id1</id1> 
</test> 
<test> 
    <id2>Some Id2</id2> 
</test> 
<test> 
    <id4>Some Id4</id4> 
</test> 
</Document> 

想要的,正確的結果產生:

<Test1>Some Id1</Test1> 
<Test2>Some Id2</Test2> 
<Test4>Some Id4</Test4> 

請注意

  1. my:test()第一個參數聲明xs:QName類型,這保證了那個價值的name attri xsl:element指令的bute始終是有效的名稱。

  2. my:test()第二個參數被聲明非常鬆散item()?型的,這給了我們自由提供任何類型的項目(字符串或節點或元素,或者......),並恰好提供了什麼會被複制「原樣」。

+0

嗨,非常感謝你的回答。我看到我自己的例子中出了什麼問題。在我自己的例子中,我沒有從xpath表達式獲取內容,但只有字符串是這樣的。我得到的原始XML有命名空間。這可能是問題嗎? – Dirk 2013-03-03 11:06:07

+0

你好Dimitre謝謝,它按預期工作。現在發生的唯一情況是我輸入的內容如下: Somde Id1我該如何擺脫空的xmlns? – Dirk 2013-03-03 13:23:14

+0

@Dirk,請提出一個新問題並提供您正在使用的確切XML文檔,以便讀者和潛在的回覆者不必猜測。 – 2013-03-03 15:31:12

2

我覺得這是最接近你要什麼:如果這是在接下來的輸入運行

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:f="custom-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <CONTENT> 
     <xsl:sequence select="f:rename('TEST1', /Document/test/id1)"/> 
     <xsl:sequence select="f:rename('TEST2', /Document/test/id2)"/> 
    </CONTENT> 
    </xsl:template> 

    <xsl:function name="f:rename"> 
    <xsl:param name="name" as="xs:string"/> 
    <xsl:param name="toWrap" /> 

    <xsl:if test="$toWrap"> 
     <xsl:element name="{$name}"> 
     <xsl:value-of select="$toWrap"/> 
     </xsl:element> 
    </xsl:if> 
    </xsl:function> 
</xsl:stylesheet> 

<Document> 
    <test> 
    <id1>Hello!</id1> 
    <id2>Hello again!</id2> 
    </test> 
</Document> 

產生的輸出是:

<CONTENT> 
    <TEST1>Hello!</TEST1> 
    <TEST2>Hello again!</TEST2> 
</CONTENT> 

你也可以試試這個,我i稍微詳細些,但XSLT 1.0兼容:

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

    <xsl:template match="/"> 
    <CONTENT> 
     <xsl:apply-templates select="/Document/test/id1" mode="rename"> 
     <xsl:with-param name="name" select="'TEST1'" /> 
     </xsl:apply-templates> 
     <xsl:apply-templates select="/Document/test/id2" mode="rename"> 
     <xsl:with-param name="name" select="'TEST2'" /> 
     </xsl:apply-templates> 
    </CONTENT> 
    </xsl:template> 

    <xsl:template match="@* | node()" mode="rename"> 
    <xsl:param name="name" /> 
    <xsl:element name="{$name}"> 
     <xsl:value-of select="." /> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

當在上面的示例XML上運行時,會再次生成相同的輸出。

+0

非常感謝你,這也是我一直在尋找的地方。正如我在上面的答案中所述。我原來的消息有名稱空間。當我在解決方案中使用xlst2解決方案時,將打印xpath表達式而不是表達式的內容。任何想法我需要做什麼來獲取內容? – Dirk 2013-03-03 11:09:11

+0

我看不出爲什麼它會打印出XPath表達式,除非你對它做了一些奇怪的事情。你能提供一個上面的例子來說明你的實際輸入XML,包括命名空間嗎? – JLRishe 2013-03-03 13:22:57

相關問題