2011-12-13 45 views
1

我有這樣的XML代碼XSLT相對或絕對路徑,意外行爲

<data> 

<proteins> 
<protein> 
<accession>111</accession> 
</protein> 
</proteins> 

<peptides> 
<peptide> 
<accession>111</accession> 
<sequence>AAA</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>AAA</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>AAA</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>BBB</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>BBB</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>BBB</sequence> 
</peptide> 
<peptide> 
<accession>111</accession> 
<sequence>BBB</sequence> 
</peptide> 
</peptides> 

</data> 

和這個XSLT代碼

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:key name="byAccSeq" match="peptide" 
          use="concat(accession, '|', sequence)"/> 
    <xsl:template match="/"> 
     <root><xsl:apply-templates select="/*/proteins/protein"/></root> 
    </xsl:template> 
    <xsl:template match="protein"> 
     <xsl:apply-templates 
      select="../../peptides/peptide[accession=current()/accession]"/> 
    </xsl:template> 
    <xsl:template match="peptide[generate-id()= 
      generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="peptide"/> 
</xsl:stylesheet> 

的輸出是這一個

<root> 
    <peptide> 
     <accession>111</accession> 
     <sequence>AAA</sequence> 
    </peptide> 
    <peptide> 
     <accession>111</accession> 
     <sequence>BBB</sequence> 
    </peptide> 
</root> 

現在,同樣XSLT代碼,但幾乎所有路徑都改爲絕對路徑

​​

不會改變任何東西。然而,如果最後路徑也表示爲絕對

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:key name="byAccSeq" match="/data/peptides/peptide" 
          use="concat(accession, '|', sequence)"/> 
    <xsl:template match="/"> 
     <root><xsl:apply-templates select="/data/proteins/protein"/></root> 
    </xsl:template> 
    <xsl:template match="/data/proteins/protein"> 
     <xsl:apply-templates 
    select="/data/peptides/peptide[accession=current()/accession]"/> 
    </xsl:template> 
    <xsl:template match="/data/peptides/peptide[generate-id()= 
      generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="/data/peptides/peptide"/> 
</xsl:stylesheet> 

那麼輸出中簡直是

<root></root> 

我沒有想到這一點。

而且,還意外地(對我來說),如果我之前寫的模板匹配,輸出再次是希望一個

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:key name="byAccSeq" match="/data/peptides/peptide" 
          use="concat(accession, '|', sequence)"/> 
    <xsl:template match="/"> 
     <root><xsl:apply-templates select="/data/proteins/protein"/></root> 
    </xsl:template> 
    <xsl:template match="/data/proteins/protein"> 
     <xsl:apply-templates 
    select="/data/peptides/peptide[accession=current()/accession]"/> 
    </xsl:template> 
    <xsl:template match="/data/peptides/peptide"/> 
    <xsl:template match="/data/peptides/peptide[generate-id()= 
      generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

最後文件:http://www.xsltcake.com/slices/sgWUFu

我想,瞭解邏輯在這之後。

回答

2

作爲@邁克爾提到的問題是template conflict resolution之一。將匹配模式從peptide更改爲/data/peptides/peptide會將模板的優先級提高到與處理/data/peptides/peptide[generate-id()= generate-id(key('byAccSeq', concat(accession, '|', sequence))[1])]的模板相同的級別。文檔中有一些節點可以通過這兩種匹配模式進行選擇,這會導致模板衝突。

這在技術上是有不止一個匹配的模板規則的錯誤,但處理器通常由文檔,這就是爲什麼改變模板的順序產生不同的結果,在將最後一個匹配模板恢復。

正如邁克爾會清楚地知道,撒克遜產生以下警告:

Recoverable error 
    XTRE0540: Ambiguous rule match for /data/peptides[1]/peptide[1] 
Matches both "/data/peptides/peptide" on line 16 of file:///C:/sandbox/so.xsl 
and "/data/peptides/peptide[generate-id()= generate-id(key('byAccSeq', concat(accession, 
    '|', sequence))[1])]" on line 13 of file:///C:/sandbox/so.xsl 
Recoverable error 
    XTRE0540: Ambiguous rule match for /data/peptides[1]/peptide[4] 
Matches both "/data/peptides/peptide" on line 16 of file:///C:/sandbox/so.xsl 
and "/data/peptides/peptide[generate-id()= generate-id(key('byAccSeq', concat(accession, 
    '|', sequence))[1])]" on line 13 of file:///C:/sandbox/so.xsl 
+0

然後,如果它應被視爲一個錯誤,是有其他選擇嗎?或者換句話說,處理器的行爲在確定哪個規則適用時是健壯的? – Gerard 2011-12-13 21:49:39

2

如果每個匹配匹配=「X」也匹配匹配節點=「/ A/B/C/X」,然後改變前者向後者的唯一作用是改變規則的優先級;該規則被認爲是更具體的,因此具有更高的優先級,當節點匹配多個規則時可能導致該規則被觸發。