LINQ to XML 和独特的自定义类
我有一个非常有趣的 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”是一个解析值以查找正则表达式匹配的函数。
有什么指点吗?
示例 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>
从这里我想要不同的 /MyPath 和 EventId(在本例中,1 个条目带有 /MyPath 和 1.My
GetApplicationNameMethod,在此示例中将返回 /MyPath
I have a very interesting LINQ question. I have a document, that I am trying to filter results on, but to filter, I am matching on a REGEX result from one element of the XML.
I have the following, working LINQ to XML to get the individual data that I'm looking for.
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
However, the .Distinct doesn't do what I want, it still shows all combinations of "ApplicationName" and "EventId".
What I need in the end is a distinct list of results, in a new object with the application name, and event id from the XML.
The "GetAPplicationName" is a function that parses the value looking for a regex match.
Any pointers?
Sample 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>
From here I want the distinct /MyPath and EventId (In this case 1 entry with /MyPath and 1.
My GetApplicationNameMethod, on this sample will return /MyPath
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
艾哈迈德的回答是正确的,我投了赞成票。不过,我只是想指出 LINQ to XML 查询的替代 VB.NET 特定语法。
这会返回相同的结果,但如果您导入 xmlns,那么您将通过这种方式获得元素名称的 IntelliSense。
以下文章介绍了如何在 VB.NET 中获取 XML IntelliSense:
http:// msdn.microsoft.com/en-us/library/bb531325.aspx
Ahmad's answer is correct and I upvoted it. However, I just wanted to point out the alternative VB.NET specific syntax for your LINQ to XML query.
This returns the same result, but if you import an xmlns, then you'll get IntelliSense for the element names this way.
Here's an article describing how to get XML IntelliSense in VB.NET:
http://msdn.microsoft.com/en-us/library/bb531325.aspx
Distinct 不知道如何比较您的项目,因此它返回所有未过滤的项目。您应该使用实现 IEqualityComparer 的独特重载。这将允许您比较 ApplicationName 和 EventId 属性以确定相等性。然而,这样做意味着拥有一个真正的类,而不是一个匿名类型。该文档演示了如何以易于理解的方式实现这一目标。
编辑:我能够将您的示例与 IEqualityComparer 和 EventInfo 类一起使用。我添加了自己的 GetApplicationName 实现来测试。
输出:
其余代码:
Distinct doesn't know how to compare your items, so it returns all the items unfiltered. You should use the Distinct overload that implements IEqualityComparer. This would allow you to compare the ApplicationName and EventId properties to determine equality. However, doing so would mean having a real class, not an anonymous type. The documentation demonstrates how to achieve this in an easy to understand manner.
EDIT: I was able to use your sample with the IEqualityComparer and an EventInfo class. I added my own implementation of GetApplicationName to test.
This outputs:
The rest of the code:
我以前从未注意到这一点,但 VB 的匿名类型似乎不会覆盖
Equals()
和GetHashcode()
。因此,Distinct()
正在检查引用相等性。最简单的解决方法是构建您自己的实现IEquatable
的类。I had never noticed this before, but it seems VB's anonymous types do not override
Equals()
andGetHashcode()
. As such,Distinct()
is checking reference equality. The easiest workaround is to build your own class that implementsIEquatable<T>
.