定义xml的相等性

时间:2012-09-04 21:45:11

标签: xml haskell

有没有办法在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,但很难找到可用的内容。

3 个答案:

答案 0 :(得分:5)

将XML解析为类似于:

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

这可以将问题简化为集合和字符串上的相等。

答案 1 :(得分:0)

大多数相等定义(例如XPath deep-equals()函数)将元素的顺序视为重要。 Saxon有一个参数化函数saxon:deep-equals()但是即使没有选项可以忽略元素顺序 - 尽管它确实有一个忽略空格的选项,所以你的(2)和(3)是相等的。您需要编写自己的函数。

答案 2 :(得分:0)

Content中的xml上可能没有Eq个实例,因为相等的定义是特定于域的。在您的应用程序中,顺序无关紧要,并且没有重复,但其他人可能会使用它们列出要在某些模拟器上执行的命令。

但这不应该阻止你。您可以向导入的数据结构添加实例。在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是您可以使用

实现顺序无关紧要的地方
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是机器生成的,那么它可能都是相同的。