xElement.descendants ( "노드")는 예상대로 작동하지 않으며 여러 수준의 자손을 반환합니다.
문제
문제가 있습니다. 다음과 같은 계층 적 XML 데이터가 있습니다.
<Tree>
<Node Text="Stuff" ItemGUID="064a9bf0-0594-47f8-87be-88dd73763c77" >
<Node Text="Food" ItemGUID="326f1f7a-d364-4838-9bdc-ce5fd93f88ca" ItemType="2" />
<Node Text="Wines" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
<Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f">
<Node Text="Red" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Pink" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="White" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
<Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
<Node Text="Sweet Delights" ItemGUID="1df7dbae-adf0-49a9-aaac-1358468a245b" />
</Node>
</Tree>
그리고 빨간색, 분홍색, 흰색 (장미 아래)없이 꽃 (장미, 튤립 등)을 가져와야하지만 다음 코드를 사용하고 있지만 모든 노드가 "노드"라는 사실 때문에 모든 수준의 Descendats를 얻습니다. . 나는 그것을 한 레벨로만 제한하고 싶습니다.
XElement loadedXML = clients.ItemTreeXML;
//filter only current node
XElement procXML;
procXML = new XElement ("Tree",
from el in loadedXML.Descendants("Node")
where (string)el.Attribute("ItemGUID") == currentNodeGUID
select el);
원하는 결과 :
<Tree>
<Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
<Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
</Tree>
감사,
추가 : 아마도 SQL 2008 쿼리는 필요한 노드 브랜치 만 리테로화 할 수 있지만 많은 연구와 테스트 후에 답을 찾을 수 없었습니다 ... (내 XML은 SQL 2008의 XML 열에 있습니다).
해결책
그래서 우리는 이것을 가지고 있습니다 ...
XElement loadedXML = XElement.Load("test.xml");
//filter only current node
XElement procXML;
procXML = new XElement("Tree",
from el in loadedXML.Descendants("Node")
where (string)el.Attribute("ItemGUID") == currentNodeGUID
select el);
내가 찾은 가장 좋은 방법은 LINQ 쿼리를 수행 한 후 모든 어린이 요소를 제거하는 것이 었습니다. 이와 같이:
foreach (XElement xl in procXML.Element("Node").Elements("Node"))
{
if (xl.HasElements) // just remove the ones without child elements
{
xl.RemoveNodes();
}
}
그것은 당신이 원하는 것을 출력하지만 추가해야합니다 ... 가장 확실하게 이것을하는 더 좋은 방법. 나는 대부분의 코드 작성 이이보다 더 역동적으로 작동해야한다는 점에서 당신의 상황과 얼마나 잘 작동할지 모르겠습니다.
나는이 질문을보고 LINQ로 뛰어 들기로 결정했습니다. 그렇게 나쁘지 않은 것 같습니다. 그것이 필요한 방식으로 작동하지 않는다면 적어도 시작입니다.
제휴하지 않습니다 StackOverflow