代码之家  ›  专栏  ›  技术社区  ›  Mitchel Sellers

linq to xml和distinct自定义类

  •  4
  • Mitchel Sellers  · 技术社区  · 15 年前

    我有一个非常有趣的LINQ问题。我有一个文档,我正在尝试筛选结果,但是为了筛选,我在一个XML元素的regex结果上进行匹配。

    我有以下内容,使用linq-to-xml获取我要查找的单个数据。

    Dim oDocument As XDocument
    oDocument = XDocument.Load("test.xml")
    Dim results = (From x In oDocument.Descendants.Elements("ROW") _
       Select New With {.ApplicationName = GetApplicationName(x.Element("Message")), _
        .EventId = x.Element("EventId")}).Distinct
    

    然而,.distinct并不能满足我的需要,它仍然显示“applicationname”和“eventid”的所有组合。

    最后,我需要的是一个不同的结果列表,在一个新的对象中,该对象具有应用程序名和XML中的事件ID。

    “getapplicationname”是一个函数,它解析值以查找regex匹配项。

    有什么指针吗?

    示例XML

    <ROOT>
      <ROW>
        <EventId>1</EventId>
        <CreatedTimestamp>2009-10-28</CreatedTimestamp>
        <Message>There is a bunch
        of 
      garbled
    inforamtion here and I'm trying to parse out a value 
    Virtual Path: /MyPath then it continues on with more junk after the
    message, including extra stuff
        </Message>
        <!--Other elements removed for brevity -->
      </ROW>
      <ROW>
        <EventId>1</EventId>
        <CreatedTimestamp>2009-10-28</CreatedTimestamp>
        <Message>
          There is a bunch
          of
          garbled
          inforamtion here and I'm trying to parse out a value
          Virtual Path: /MyPath then it continues on with more junk after the
          message, including extra stuff
        </Message>
        <!--Other elements removed for brevity -->
      </ROW>
    </ROOT>
    

    从这里,我需要distinct/mypath和eventid(在本例中,1个条目带有/mypath和1)。

    在此示例上,我的getapplicationnamemethod将返回/mypath

    3 回复  |  直到 15 年前
        1
  •  1
  •   Ahmad Mageed    15 年前

    Distinct overload that implements IEqualityComparer

        Dim results = (From x In doc.Descendants.Elements("ROW") _
           Select New EventInfo With {.ApplicationName = GetApplicationName(x.Element("Message")), _
            .EventId = x.Element("EventId")})
    
        Console.WriteLine("Total: {0}", results.Count)
        Console.WriteLine("Distinct Total: {0}", results.Distinct.Count)
        Console.WriteLine("Distinct (w/comparer) Total: {0}", results.Distinct(New EventInfoComparer()).Count)
    

    Total: 2
    Distinct Total: 2
    Distinct (w/comparer) Total: 1
    

    ' EventInfo class and comparer
    Private Function GetApplicationName(ByVal element As XElement)
        Return Regex.Match(element.Value, "Virtual\sPath:\s/(\w+)").Groups(1).Value
    End Function
    
    Public Class EventInfo
        Private _applicationName As String
        Public Property ApplicationName() As String
            Get
                Return _applicationName
            End Get
            Set(ByVal value As String)
                _applicationName = value
            End Set
        End Property
    
        Private _eventId As Integer
        Public Property EventId() As Integer
            Get
                Return _eventId
            End Get
            Set(ByVal value As Integer)
                _eventId = value
            End Set
        End Property
    End Class
    
    Public Class EventInfoComparer
        Implements IEqualityComparer(Of EventInfo)
    
        Public Function Equals1(ByVal x As EventInfo, ByVal y As EventInfo) As Boolean _
            Implements IEqualityComparer(Of EventInfo).Equals
    
            ' Check whether the compared objects reference the same data.
            If x Is y Then Return True
    
            ' Check whether any of the compared objects is null.
            If x Is Nothing OrElse y Is Nothing Then Return False
    
            ' Check whether the EventInfos' properties are equal.
            Return (x.ApplicationName = y.ApplicationName) AndAlso (x.EventId = y.EventId)
        End Function
    
        Public Function GetHashCode1(ByVal eventInfo As EventInfo) As Integer _
            Implements IEqualityComparer(Of EventInfo).GetHashCode
    
            ' Check whether the object is null.
            If eventInfo Is Nothing Then Return 0
    
            ' Get the hash code for the ApplicationName field if it is not null.
            Dim hashEventInfoAppName = _
                If(eventInfo.ApplicationName Is Nothing, 0, eventInfo.ApplicationName.GetHashCode())
    
            ' Get the hash code for the EventId field.
            Dim hashEventInfoId = eventInfo.EventId.GetHashCode()
    
            ' Calculate the hash code for the EventInfo.
            Return hashEventInfoAppName Xor hashEventInfoId
        End Function
    End Class
    
        2
  •  2
  •   CoderDennis    15 年前

    Dim results = From x In doc...<ROW> _
       Select New EventInfo With {.ApplicationName = GetApplicationName(x.<Message>.Value, _
        .EventId = x.<EventId>.Value}
    

    http://msdn.microsoft.com/en-us/library/bb531325.aspx

        3
  •  1
  •   dahlbyk    15 年前

    Equals() GetHashcode() Distinct() IEquatable<T>