2

有没有办法在 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没有帮助,因为.EqContent

此外,xml-conduit也不可用,因为Element它包含List. 它对空格也很敏感。

有许多库可以使用,xml包括HXT但很难找到可用的东西。

4

3 回答 3

5

将 XML 解析为类似于以下内容的结构:

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

这将问题减少到集合和字符串的相等性。

于 2012-09-04T23:36:37.507 回答
0

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

于 2012-09-05T07:02:19.043 回答
0

xml中可能没有Eq实例,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 的更高版本添加构造函数更难看,但至少会出现编译器错误。)

你可以ContentElement

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有点棘手,并且可能有不同的方式来表示同一个字符串,所以仅仅检查cdDataString 可能还不够;您可能需要将所有内容转换CDdata为使用相同CDataKind或其他内容。另一方面,如果您的 xml 是机器生成的,那么无论如何它可能都是一样的。

于 2012-09-05T12:45:01.057 回答