2012-09-04 26 views
2

有沒有一種方法可以定義Xml語句上的相等性,以使這三者相同(忽略空格和參數以及標記順序)?定義xml的相等

1:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com</groupId> 
    <url>http://maven.apache.org</url> 
</project> 

2:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <url>http://maven.apache.org</url> 
    <groupId>com</groupId> 
</project> 

3:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <url>http://maven.apache.org</url> 
    <groupId>com</groupId> 
</project> 

例如,xml是沒有幫助的,因爲有上Content沒有Eq實例。

此外,xml-conduit也不可用,因爲Element包含List中的所有節點元素。它也對空格敏感。

有許多圖書館與xml工作,包括HXT但很難找到可用的東西。

+0

答案:'是'?也許我不明白你的問題 - 定義是什麼意思? –

+1

你的意思是「我怎樣才能定義Xml語句上的相等,這三個是相同的?」? – AndrewC

+0

@AndrewC,是的。 HXT中有許多庫,但我找不到一種正常化xml的方法。 –

回答

5

解析XML成爲類似某種結構:

data Tree = TreeNode (Set Tree) | LeafNode String deriving Eq 

這降低了問題就集和字串平等。

+0

..或甚至是特定於數據類型的數據類型,例如'data Project = Project {modelVersion :: Version,url :: URL,groupID :: String}派生Eq',使用cleverer解析器 – AndrewC

0

等號的大多數定義(例如XPath deep-equals()函數)將元素的順序視爲重要。撒克遜有一個參數化函數saxon:deep-equals(),但即使沒有選項可以忽略元素順序 - 儘管它有一個選項可以忽略空格,所以你的(2)和(3)是相等的。你將需要編寫自己的功能。

0

可能沒有Eq實例,因爲xml中的Content,因爲等式的定義是特定於域的。在您的應用程序中,順序無關緊要,並且沒有重複,但其他人可能會使用它們來列出要在某些模擬器上執行的命令。

雖然這不應該阻止你。您可以將實例添加到導入的數據結構。在Text.XML.Light.Types我們看到

data CData = CData { 
       cdVerbatim :: CDataKind, 
       cdData  :: String, 
       cdLine  :: Maybe Line 
      } 

,所以我們可以定義

instance Eq CData where 
    CData v d l == CData v' d' l' = and [v==v',d==d',l==l'] 

(我認爲這是比cd==cd' = cdVerbatim cd == cdVerbatim cd' && ....醜陋,但你至少得到一個編譯錯誤,如果XML的後續版本增加了構造函數。 )

你可以做同樣定義爲Content,但Element在這裏你可以與

實現訂單doesn't事項
instance Eq Element where 
    Element n as cs l == Element n' as' cs' l' = and 
      [n==n', 
      as==as', 
      all (`elem` cs) cs', 
      all (`elem` cs') cs, 
      l==l'] 

您可以將空白刪除添加到您創建的Eq實例,但不添加到其他數據類型。如果您需要修改它們,您可以定義自己的same函數,並在您的Eq實例中使用它來代替==

我有點擔心CData有點棘手,並且可能有不同的方式來表示相同的字符串,所以只需檢查cdData字符串可能是不夠的;您可能需要將所有CDdata轉換爲使用相同CDataKind或其他東西。另一方面,如果你的xml是機器生成的,它可能都是一樣的。