有没有办法在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-conduit也不可用,因为Element
包含List
中的所有节点元素。它也对空白很敏感。
有许多库可以与xml
一起使用,包括HXT
,但很难找到可用的内容。
答案 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是机器生成的,那么它可能都是相同的。