2011-12-13 11 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> 

及び出力は今、同じこれ

<root> 
    <peptide> 
     <accession>111</accession> 
     <sequence>AAA</sequence> 
    </peptide> 
    <peptide> 
     <accession>111</accession> 
     <sequence>BBB</sequence> 
    </peptide> 
</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="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> 

このXSLTコードを有しますほとんどすべてのパスが絶対パスに変更された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> 

である私はこれを期待していませんでした。私は前にテンプレートマッチングを書いた場合、出力は再び望んだ1

<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

@Michaelが示唆したように、問題はのいずれかです。一致パターンを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

+0

@ジェラード - そうすべきです。 「XSLTプロセッサはエラーを通知するかもしれませんが、エラーを通知しなければ、スタイルシートで最後に発生したものと一致するテンプレートルールの中から選択することで回復する必要があります。 http://www.w3.org/TR/xslt#conflict –

2

match = "x"と一致するすべてのノードもmatch = "/ a/b/c/x"と一致する場合、前者を後者に変更する唯一の効果はルールの優先度を変更することです。ルールはより具体的であり、したがってより高い優先度と見なされ、ノードが複数のルールに一致するときにルールが起動される可能性があります。