2012-09-04 3 views
2

Existe-t-il un moyen de définir l'égalité sur les instructions Xml telles que ces trois sont les mêmes (en ignorant les espaces et les arguments et l'ordre des balises)?Définir l'égalité de 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> 

Par exemple, xml n'est pas utile, car il n'y a pas Eq instance sur Content.

En outre, xml-conduit n'est pas utilisable aussi, car Element contient tous les éléments de noeud dans List. En outre, il est sensible aux espaces blancs.

Il existe de nombreuses bibliothèques pour travailler avec xml, y compris HXT mais il est difficile de trouver quelque chose d'utilisable.

+0

La réponse est-elle «oui»? Peut-être que je ne comprends pas votre question - que voulez-vous dire par définir? –

+1

Voulez-vous dire "Comment puis-je définir l'égalité sur les instructions Xml telles que ces trois sont les mêmes?"? – AndrewC

+0

@AndrewC, oui. Il y a beaucoup de bibliothèques dans HXT mais je ne trouve pas de méthode pour normaliser xml. –

Répondre

5

parser le XML dans une structure similaire à:

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

Cela réduit le problème à l'égalité sur les ensembles et les chaînes.

+0

..ou même des types de données spécifiques aux problèmes comme 'data Project = Projet {modelVersion :: Version, URL :: URL, groupID :: String} dérivant Eq', utilisant un analyseur plus intelligent – AndrewC

0

La plupart des définitions d'égalité (par exemple la fonction XPath deep-equals()) traitent l'ordre des éléments comme significatif. Saxon a une fonction paramétrée saxon: deep-equals() mais qui n'a pas d'option pour ignorer l'ordre des éléments - bien qu'il ait une option pour ignorer les espaces, ainsi votre (2) et (3) seraient égaux. Vous devrez écrire votre propre fonction.

0

Probablement il n'y a aucun cas Eq sur Content en xml parce que la définition de l'égalité est spécifique au domaine. Dans votre application, l'ordre n'a pas d'importance et il n'y a pas de répétitions, mais quelqu'un d'autre peut les utiliser pour lister les commandes à exécuter sur un émulateur.

Cela ne devrait pas vous arrêter, cependant. Vous pouvez ajouter des instances aux structures de données importées. En Text.XML.Light.Types nous voyons que

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

afin que nous puissions définir

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

(je pense que cela est plus laid que cd==cd' = cdVerbatim cd == cdVerbatim cd' && .... mais vous aurez au moins obtenir une erreur de compilation si une révision ultérieure de xml ajoute constructeurs.)

vous pouvez faire le même genre de définition pour Content, mais Element est où vous pouvez mettre en œuvre ordre doesnt-matière avec

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'] 

Vous pouvez ajouter la suppression d'espaces aux instances Eq que vous créez, mais pas aux autres types de données. Si vous avez besoin de les réviser, vous pouvez définir votre propre fonction same et l'utiliser au lieu de == dans vos instances Eq.Je suis un peu inquiet que CData soit un peu épineux, et il pourrait y avoir différentes façons de représenter la même chaîne, donc il suffit de vérifier la chaîne cdData peut-être pas assez; vous devrez peut-être convertir tous CDdata pour utiliser le même CDataKind ou quelque chose. D'un autre côté, si votre fichier XML est généré par une machine, il se peut que tous les fichiers soient identiques.

Questions connexes