2014-03-13 78 views
0

我有一個XSLT 1.0的比賽是這樣的:有沒有更簡單的方法來編寫這個XSLT匹配?

<xsl:template match="/ns:Library/ns:Book/@title | /ns:Library/ns:Book/@author | /ns:Library/ns:Book/@isbn | /ns:Library/ns:Book/@publisher"/> 

有沒有寫這個較短的方法嗎?

我希望這樣的事情:

<xsl:template match="/ns:Library/ns:Book/@*[title|author|isbn|publisher]"/> 

但顯然不起作用。

回答

2

寫你嘗試什麼正確的方法是:

<xsl:template match="/ns:Library/ns:Book/@*[name() = 'title' or name() = 'author' or name() = 'isbn' or name() = 'publisher']"/> 

這當然不是真的大大縮短。但也有其他的方式來編寫代碼,更簡潔:

1編寫不同的模板元素和屬性相匹配

爲了避免過長的表情,你可以你的代碼拆分爲單獨的模板。在第一個模板,匹配的元素:

<xsl:template match="/ns:Library/ns:Book"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*"/> 
    </xsl:copy> 
</xsl:template> 

然後,寫一個模板的屬性:

<xsl:template match="@title|@author|@isbn|@publisher"> 
    <!--Process attributes--> 
</xsl:template> 

2指定哪些屬性應當匹配

<xsl:template match="/ns:Library/ns:Book/@*[name() != 'date']"/> 

最終,它取決於您的輸入XML數據和XSLT上下文,無論這些方法是否有意義。例如,如果有100個你不想匹配的屬性,那麼第二個想法是沒有用的。

您的主要關注點應該是準確性(產生正確的輸出XML),其次是代碼的可讀性。如果對XSLT代碼的更改不能改善其中的任何一種,那麼更改樣式表可能是一個壞主意。

+0

@nwellnhof你是對的 - 感謝糾正。 –

1

XSLT是非常多的上下文驅動。沒有看到這個模板是如何(從哪個上下文)被應用的(並且沒有看到XML和樣式表的其餘部分),任何答案都是猜測。從技術上講,你可以寫:

<xsl:template match="@title|@author|@isbn|@publisher"/> 

並從/ns:Library/ns:Book的上下文應用此模板。


請記住,XSLT自然是冗長的,簡潔性很少成爲最優先考慮的事情。

+0

+1,比賽結束時有一個多餘的']'。乾杯! –

+0

@MathiasMüller謝謝! –

0

在XSLT 3.0,你可以寫

match="/ns:Library/ns:Book/(@title | @author)" 

在1.0一個可能的選擇是

match="/ns:Library/ns:Book/@*[name()='author' or name()='title']" 

但我更喜歡原來冗長。至少在撒克遜人(我不能說其他處理器)匹配顯式名稱的模式總是比匹配通配符(*或@ *)並且依賴於謂詞的模式快得多。

您確定您確實需要"/ns:Library/ns:Book/"部件嗎?你確定match="@title|@author"不會做這份工作嗎?

+0

我確實需要上下文,因爲有問題的屬性出現在原始XML文件中,但我需要將「覆蓋」應用於單個節點。 (這是一個基於更復雜的例子) – nielsbot

0

有關,即與XSLT 1.0較短的緣故我經常寫類似:

<xsl:template match="/ns:Library/ns:Book/@*[contains('title|author|isbn|publisher',name())]"/> 

或使用全局變量:

<xsl:variable name="attrNames">title|author|isbn|publisher</xsl:variable> 

<xsl:template match="/ns:Library/ns:Book/@*[contains($attrNames,name())]"/> 

編輯

正如@ nwellnhof提到,這也包括僅匹配部分字符串的屬性,如it,authsbpub等等,所以這隻有在這些情況已知不存在時纔有意義。


在XSLT 2.0我首選的解決方案是:

<xsl:variable name="attrNames" select="'title','author','isbn','publisher'"/> 

<xsl:template match="/ns:Library/ns:Book/@*[name() = $attrNames]"/> 
+0

這將包括'it','auth','sb','pub'等屬性。 – nwellnhof

+0

@nwellnhof當然,你必須知道你的xml結構,以確保其中沒有其他屬性。 –

相關問題