2011-03-10 49 views
1

我想通過XSLT比較兩個XML文件。比較應當被認爲是成功的,如果在文檔1中的特定類型的所有元件被定位在文件相同的XPath位置2XSLT:兩個文件之間的XPath比較

考慮

<entry> 
    <entry1> 
     <entry2> 
      <value type="1"/> 
     </entry2> 
    </entry1> 
</entry> 

如文獻1

的被觀察的元素是位於entry/entry1/entry2處的「值」(屬性類型= 1)。因此,在這個意義上說,以

<entry> 
    <entry0/> 
    <entry0/> 
    <entry1> 
     <entry2> 
      <value type="1"/> 
     </entry2> 
    </entry1> 
</entry> 

的比較應該被認爲是成功的,而

<entry> 
    <entry1> 
     <value type="1"/> 
    </entry1> 
</entry> 

不成功,因爲「值」(與屬性類型= 1)位於入口/取值範。也 比較結果來

<entry> 
    <entry1> 
     <entry2> 
      <value type="2"/> 
     </entry2> 
    </entry1> 
</entry> 

應當被認爲是不成功的,因爲價值的屬性的類型= 2。

我天真的試驗,以履行其在XSLT這個任務是這樣的:

<xsl:template match="value"> 
    <xsl:if test="not(document($doc2)/.[@[email protected]])"> 
     <xsl:text>something is missing</xsl:text> 
    </xsl:if> 
</xsl:template> 

這種做法並不成功,因爲第2文件中所需的XPath的選擇似乎不起作用。

也許你有一個想法如何解決這個問題?

馬特

+0

如果您只需測試一些元素,最好的方法是手動編寫測試XPath,然後針對不同的文件執行它們並比較結果。否則,我不知道這個問題的簡單解決方案。 – 2011-03-10 13:41:23

+0

我不明白你的比較。 '<值類型= 「1」/>'是從'條目><值類型= 「1」/>非常不同'。爲什麼他們之間的比較成功? – 2011-03-10 13:45:25

+0

好吧,不要稱之爲「比較」,而是「檢查doc1中觀察到的每個元素是否存在於doc2中相同的XPath」。我將嘗試下面的答案中提出的深入平等。 – Matt 2011-03-10 14:36:41

回答

0

只是爲了好玩,Kay博士的answer的XSLT 1.0譯文:

<xsl:variable name="vTest1"> 
     <xsl:for-each select="$D1//value[@type]"> 
      <xsl:variable name="vPath1"> 
       <xsl:for-each select="ancestor-or-self::*"> 
        <xsl:value-of select="concat('/',name())"/> 
       </xsl:for-each> 
      </xsl:variable> 
      <xsl:variable name="vTest2"> 
       <xsl:for-each select="$D2//value[@type=current()/@type]"> 
        <xsl:variable name="vPath2"> 
         <xsl:for-each select="ancestor-or-self::*"> 
          <xsl:value-of select="concat('/',name())"/> 
         </xsl:for-each> 
        </xsl:variable> 
        <xsl:if test="$vPath1=$vPath2">True</xsl:if> 
       </xsl:for-each> 
      </xsl:variable> 
      <xsl:if test="$vTest2=''">False</xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 

然後$vTest1 = ''將是測試的布爾值。

+0

+1 for 1.0解決方案。 – Flack 2011-03-10 17:07:08

+0

非常感謝,解決方案几乎是1:1適用於我的問題。 – Matt 2011-03-11 09:05:50

2

你的問題是絕望的低估。例如,除了要求doc1中的每個元素在doc2中具有相應的元素之外,還需要doc2中的每個元素在doc1中具有相應的元素嗎?

然而,一些接近可能的條件「在D1這樣name(V1)=N每個元素V1,存在一個元素V2D2這樣name(V2)=N and deep-equal(V1, V2) and path(V1) = path(V2),其中path($ V)被定義爲string-join($V/ancestor-or-self::*/name()),翻譯到下面的XPath 2.0表達式:

every $V1 in $D1//N satisfies 
some $V2 in $D2//N satisfies 
deep-equal($V1, $V2) and 
string-join($V1/ancestor-or-self::*/name()) 
= string-join($V2/ancestor-or-self::*/name()) 
+0

對不起,如果你認爲我的問題沒有詳細說明,我只是想着重於主要方面。特別是你的例子並不相關:doc2可能包含大量其他元素,這些元素不會影響我的意義上的比較(所以可能是「比較」這個詞是誤導性的 - 對此抱歉!)無論如何,謝謝你的想法的確有幫助。 – Matt 2011-03-10 14:28:10

+0

+1優秀的答案,非常正式,但一般。 – 2011-03-10 15:08:32

+0

+1。確實很棒。 – Flack 2011-03-10 17:06:15