【发布时间】:2014-06-18 12:12:37
【问题描述】:
我有第三方发送的 xml,我想对其进行验证。
XElement xTree = XElement.Parse(@"<Container>
<TrackingReferences>
<TrackingReference>
<TrackingName>Donny</TrackingName>
<TrackingCodes>
<TrackingCode>
<Name></Name>
</TrackingCode>
<TrackingCode>
<Name>DisplayThis</Name>
</TrackingCode>
<TrackingCode>
<Name></Name>
</TrackingCode>
</TrackingCodes>
</TrackingReference>
</TrackingReferences>
</Container>");
IEnumerable<XElement> childList = xTree.Element("TrackingReferences").Descendants("TrackingReference").Where(
tr => (
tr.Element("TrackingName") != null && !tr.Element("TrackingName").IsEmpty && !String.IsNullOrEmpty(tr.Element("TrackingName").Value) &&
tr.Descendants("TrackingCodes").Any(
tc => tc.HasElements &&
tc.Elements("TrackingCode").Any(
code => code.Element("Name") != null && !code.Element("Name").IsEmpty && !String.IsNullOrEmpty(code.Element("Name").Value)
)
)
)
);
我不知道如何返回我想要的后代。
我遇到的问题是,当 TrackingCode 具有 Name 不为 null 或空的元素。
下面的例子返回:
<TrackingReference>
<TrackingName>Donny</TrackingName>
<TrackingCodes>
<TrackingCode>
<Name></Name>
</TrackingCode>
<TrackingCode>
<Name>DisplayThis</Name>
</TrackingCode>
<TrackingCode>
<Name></Name>
</TrackingCode>
</TrackingCodes>
</TrackingReference>
但是在这个例子中,我不希望返回第一个和第三个 TrackingCode 元素,只返回第二个,因为它有一个 Name 元素,像这样:
<TrackingReference>
<TrackingName>Donny</TrackingName>
<TrackingCodes>
<TrackingCode>
<Name>DisplayThis</Name>
</TrackingCode>
</TrackingCodes>
</TrackingReference>
这是我第一次尝试对 XML 进行 LINQ 查询,因此,如果我以错误的方式处理此问题,将非常感谢任何有关如何使查询更简洁/高效的建议。
【问题讨论】:
-
您真的想要修改版本的 TrackingReference 元素,还是对具有非空名称的 TrackingCode 元素序列感到满意?后者要简单得多。
-
假设您想要一个修剪过的文档,Xsl 转换可能更适合这个问题?
-
@JonSkeet - 后者;一系列具有非空名称的 TrackingCode 元素,因此在上面的示例中,将只返回一个 TrackingCode 元素而不是三个 TrackingCode 元素(因为查询当前正在返回)。非常感谢。
-
@StuartLC - 我最终可能会选择 XSLT,但由于我没有做太多 LINQ to XML 我希望挑战能够更好地理解它
标签: .net xml linq xelement descendant