如何比较两个 XElement 枚举?

How to compare two XElement enumerables?

我有两个大小相等的 XElements 列表:

var documentDatabase = XDocument.Parse(xmlDatabase);
var rootElementDatabase = documentDatabase.Root;
var segmentsDatabase = rootElementDatabase.Descendants("Segment");

var documentSlave = XDocument.Parse(xmlSlave);
var rootElementSlave = documentSlave.Root;
var segmentsSlave = rootElementSlave.Descendants("Segment");

基本上是 Segment 元素的列表,如下所示:

        <Segment>
            <IdRef>1</IdRef>
            <Start>
                <Master>0</Master>
                <Slave>0</Slave>
                <PntType>4</PntType>
            </Start>
            <End>
                <Master>10.059000</Master>
                <Slave>29.450302</Slave>
                <PntType>4</PntType>
            </End>
            <Symmetry>0.5</Symmetry>
            <FunctionType>1</FunctionType>
        </Segment>

我想要的是通过比较 <Master><Slave> 标签中的值来比较它们是否相等,忽略其余部分。我怎样才能实现它?

如果要比较Start和End中的Master和Slave标签,可以用这个方法:

bool CompareXmls(XElement first, XElement second)
{
        var firstStart = first.Element("Start");
        var firstEnd = first.Element("End");
        var firstStartMaster = firstStart.Element("Master").Value;
        var firstStartSlave = firstStart.Element("Slave").Value;
        var firstEndMaster = firstEnd.Element("Master").Value;
        var firstEndSlave = firstEnd.Element("Slave").Value;

        var secondStart = second.Element("Start");
        var secondEnd = second.Element("End");
        var secondStartMaster = secondStart.Element("Master").Value;
        var secondStartSlave = secondStart.Element("Slave").Value;
        var secondEndMaster = secondEnd.Element("Master").Value;
        var secondEndSlave = secondEnd.Element("Slave").Value;

        bool areEqual = firstStartMaster == secondStartMaster
            && firstStartSlave == secondStartSlave
            && firstEndMaster == secondEndMaster
            && firstEndSlave == secondEndSlave;

        return areEqual;
    }

编辑:想要比较已经排序的列表,您可以将一个列表中的第一项与另一个列表中的第一项进行比较,依此类推,您可以使用 LINQ .Zip 方法将 XElements 分组到一个匿名对象中,然后然后使用 LINQ .All 循环遍历项目并进行比较:

var res = firstList.Zip(secondList, (a, b) => new { First = a, Second = b }).All(x=>CompareXmls(x.First,x.Second));

就我个人而言,我可能会使用 for 循环遍历两个列表并比较每一项,但如果您想使用单行 LINQ,则可以使用上述方法。

如果您有多个细分,请创建一个方法来比较它们

Private Function ChkSeg(segment As XElement) As Boolean
    If segment.<Start>.<Master>.Value = segment.<End>.<Master>.Value AndAlso
         segment.<Start>.<Slave>.Value = segment.<End>.<Slave>.Value Then
        Return True
    Else
        Return False
    End If
End Function

然后像这样迭代 XML

    For Each el As XElement In xe.Elements
        If ChkSeg(el) Then
            Stop
        Else
            Stop
        End If
    Next

使用这个测试

    Dim xe As XElement

    xe = <segments>
             <Segment>
                 <IdRef>1</IdRef>
                 <Start>
                     <Master>0</Master>
                     <Slave>0</Slave>
                     <PntType>4</PntType>
                 </Start>
                 <End>
                     <Master>10.059000</Master>
                     <Slave>29.450302</Slave>
                     <PntType>4</PntType>
                 </End>
                 <Symmetry>0.5</Symmetry>
                 <FunctionType>1</FunctionType>
             </Segment>
             <Segment>
                 <IdRef>1</IdRef>
                 <Start>
                     <Master>0</Master>
                     <Slave>0</Slave>
                     <PntType>4</PntType>
                 </Start>
                 <End>
                     <Master>0</Master>
                     <Slave>0</Slave>
                     <PntType>4</PntType>
                 </End>
                 <Symmetry>0.5</Symmetry>
                 <FunctionType>1</FunctionType>
             </Segment>
         </segments>