2012-05-04 278 views
4

是否可以匹配'任何節點尚未匹配/處理'?最好不要讓我的樣式表變成一個巨大的for-each/Choose語句,因爲當前的排序很關鍵。任何節點尚未處理的XSLT模板?

該項目仍在開發中,並且已經在現場環境中使用,所以簡單地說,代碼處於快速流動的狀態,以響應我們獲取的實時數據。我正在生成PDF文檔通過FO從XML中獲取可能包含我還不知道的節點的XML,並且希望爲我的XSL-FO轉換添加一個「故障轉移」指令,將所有未記錄的節點置於文檔的開頭以鮮紅色,加快發現。

我不能只是忽略突然的節點,因爲數據需要要處理。我可以找到「孤兒」數據的速度越快,我可以更快地得到它的正確處理和出門。

我試着玩<xsl:template match="*">...</xsl:template>和各種priority =「」設置,但它當然適用於每個節點。

例如,我可能在一個部分有這個,因爲這些XML塊不能保證輸入順序正確。 (代碼塊格式化是不是爲我工作 - 在沒有四個空間縮進結果,很抱歉:(

<xsl:template match="AccountSummary"> 
    <fo:block margin-left="2" space-before="1" space-after="1" text-align="center"> 
     <xsl:apply-templates select="Label"/> 
    </fo:block> 
    <xsl:apply-templates select="AccountInfo"/> 
    <xsl:apply-templates select="AccountProfile"/> 
    <xsl:apply-templates select="ChangeInValueOfAccounts"/> 
    <!-- ... more goes here --> 
</xsl:template> 

我想這樣做

<xsl:template match="AccountSummary"> 
    <fo:block margin-left="2" space-before="1" space-after="1" text-align="center"> 
     <xsl:apply-templates select="Label"/> 
    </fo:block> 
    <xsl:apply-templates select="AccountInfo"/> 
    <xsl:apply-templates select="AccountProfile"/> 
    <xsl:apply-templates select="ChangeInValueOfAccounts"/> 
    <!-- ... more goes here --> 
    <xsl:for-each select="not otherwise matched"> 
     <!-- call zomgRED template --> 
    </xsl:for-each> 
</xsl:template> 

理想我寧願在zomgRED s到在頂部,但在底部也可以工作,或者用文本標記標記,任何東西都可以在最終文檔中吐出文本,而不是默默地吃掉它

+2

由於XSLT優先匹配基於模板特異性的顯式層次結構,除此之外,您應該可以使用'match ='*''。如果您發佈了一個小樣本XML和XSLT,它可能會有所幫助。將所有未知節點放置在頂部的要求將會很難,因爲在整個文檔處理完成之前,您不知道哪些節點是不匹配的。 –

+0

啊,我當然忘了逃避我的< s。我可以應付「按順序」或必要時在任何地方,但在頂部會更簡單。 – BrunoXSLT

+0

向原始帖子添加了轉義。簡而言之,當我嘗試使用< xsl:template match =「*」> < fo:block> ##### < xsl:apply-templates />&lt; xsl:template>它適用於而不是任何其他模板通過match =而不是select =來應用,並且突然間每個節點都會在其前面用#####自己的塊吐出:/ – BrunoXSLT

回答

2

下面是如何獲得一些你在找什麼。雖然沒有推動未來ocessed節點到頂部:

1)在你的樣式表中的身份轉換:

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

2)請確保調用所有其他更具體的模板<xsl:apply-templates select="*"/>讓解析器會

這個想法是,您的特定模板處理到XSL-FO的預期轉換,而標識轉換隻是將其他所有內容轉儲到結果樹中。遞歸調用將確保您實際觸及所有節點(這是讓他們「記錄下來」的唯一方法),並且身份轉換將匹配那些您沒有注意到的情況。

#2建議實際上可以獲得您XSL-FO邏輯的一種方式,因此可能並不可行,我不能說明沒有示例輸入和當前的XSL-FO轉換。也許把它添加到問題?

0

note:原來的答案完全取代基於更新的問題。

你可以這樣做,但你需要列出這些項目,你不想讓zomgRed模板第二次:

<xsl:template match="AccountSummary"> 
    <fo:block margin-left="2" space-before="1" space-after="1" text-align="center"> 
     <xsl:apply-templates select="Label"/> 
    </fo:block> 
    <xsl:apply-templates select="AccountInfo"/> 
    <xsl:apply-templates select="AccountProfile"/> 
    <xsl:apply-templates select="ChangeInValueOfAccounts"/> 
    <-- ... more goes here --> 
    <xsl:apply-templates mode='fallback' select * /> 

</xsl:template> 

<xsl:template match='AccountInfo|AccountProfile|ChangeInValueOfAccounts| ... more goes here' mode='fallback' /> 

<xsl:template match='*' mode='fallback'> 
    <!-- call zomgRED template --> 
</xsl:template> 

我已經更換了你for-each另一個apply-templates,但現在我們正在使用一種模式。只有相同模式下的模板纔會匹配。匹配「*」的模板只能匹配該模式,所以在其他情況下不會被調用。單行模板以相同的模式匹配,並匹配您已經處理的所有節點,並且不執行任何操作。由於它比「*」更具體,因此它將運行(而不執行任何操作)而不是這些節點的「*」模板。

作爲帶有重複節點列表的單行模板的替代方案,可以將相同的模式添加到所有現有模板(AccountInfo,AccountProfile等)以及每個模板的apply-templates語句中。這是一個風格問題,你會發現它更易於維護。

0

下面是一個例子,如何可以做到這一點(只跟蹤無與倫比的節點 - 如果有必要無與倫比的屬性跟蹤可以以同樣的方式來實現):

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

<!-- Catch all node - types template -- must be the top-most --> 
<xsl:template match="node()"> 
    Warning: this node is unmatched by any templates: 

    "<xsl:copy-of select="."/>" 
</xsl:template> 

<xsl:template match="nums"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="num[following-sibling::num[1] -1 = .]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉化應用上下面的XML文檔:(有意選擇很簡單,爲了說明這個簡單的解決方案)

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

,結果產生,其中包括一個無與倫比的元素警告:

<num>01</num> 
<num>02</num> 
<num>03</num> 
<num>04</num> 
<num>05</num> 
<num>06</num> 
<num>07</num> 
<num>08</num> 
<num>09</num> 
    Warning: this node is unmatched by any templates: 

    "<num>10</num>" 

請注意:如果stylesheet導入/包括其他樣式表此解決方案將無法工作。在這種情況下,全部模板必須放置在首先出現的樣式表中(或者具有最低的導入優先級)。