2011-09-20 3 views
1

XML 파일의 일부가 GoodsItems 요소 인 곳이 있습니다. 서브 요소가 SupplementaryInformationLines.SupplementaryInformationLine이고 서브 번호가 Code == "X002"이고 Text != "NLR" 인 요소가 먼저 오도록 GoodsItem 요소를 주문하고 싶습니다. 결과적으로 모든 요소는 GoodsItem.TaricCode 요소에 의해 정렬되어야합니다.Linq to subelements에서 정렬하여 XML 정렬/orderby 문제

<GoodsItems> 
    <GoodsItem> 
    <GoodsDescription1>Some goods to be sorted last</GoodsDescription1> 
    <TaricNumber>854129</TaricNumber> 
    <SupplementaryInformationLines> 
     <SupplementaryInformationLine> 
     <Type>B.H</Type> 
     <Code>X002</Code> 
     <Text>NLR</Text> 
     </SupplementaryInformationLine> 
     <SupplementaryInformationLine> 
     <Type>SU</Type> 
     <Code></Code> 
     <Text>Some text</Text> 
     </SupplementaryInformationLine> 
    </SupplementaryInformationLines> 
    </GoodsItem> 
    <GoodsItem> 
    <GoodsDescription1>Some goods to be sorted first</GoodsDescription1> 
    <TaricNumber>854129</TaricNumber> 
    <SupplementaryInformationLines> 
     <SupplementaryInformationLine> 
     <Type>B.H</Type> 
     <Code>X002</Code> 
     <Text>SE_A_4324234</Text> 
     </SupplementaryInformationLine> 
     <SupplementaryInformationLine> 
     <Type>SU</Type> 
     <Code></Code> 
     <Text>Some text</Text> 
     </SupplementaryInformationLine> 
    </SupplementaryInformationLines> 
    </GoodsItem> 
</GoodsItems> 

내가 그것을 테스트 순서의 첫 번째 부분은 제대로 작동하려면 그것을 가지고, 그때는 TaricNumber 순서를 추가 where 절 캐스팅에 요소의 문자열 값을 얻을 수 .Value를 사용하여 변경 .Value를 사용할 때 일부 파일에 NullPointerException이 발생하기 때문에 대신 문자열을 사용하십시오. 이러한 변경 후에 나는 다시 작동하게 할 수 없다. TaricNumber 만 GoodsItems를 주문합니다.

var query = from xeGoodsItem in xeCustClearance.Element(nsName + "GoodsItems").Elements(nsName + "GoodsItem") 
    let sortValue1 = (
     from xeSuppInfo in xeGoodsItem.Element(nsName + "SupplementaryInformationLines").Elements(nsName + "SupplementaryInformationLine") 
     where ((string)xeSuppInfo.Element("Code") == "X002" && (string)xeSuppInfo.Element("Text") != "NLR") 
     select 1).FirstOrDefault() 
    orderby sortValue1 descending, (string)xeGoodsItem.Element(nsName + "TaricNumber").Value ascending 
    select xeGoodsItem; 

XML 파일을 순서와 함께 저장할 필요가 없습니다. 메모리 내 정렬 만 수행합니다. linq 쿼리 대신 ReplaceNode approach을 사용하는 것도 해결책이 될 수 있지만이 작업을 수행하기 만하면됩니다.

+0

코드가 좋게 보이며, 그 xml과 그 쿼리로 최소한의 예제가 필요할 때 먼저'to be sorted first' 엘리먼트를 먼저 반환합니다. – AakashM

+0

흠, 그게 나에게 단서를 주어야합니다. GoodsItems는 더 큰 xml 파일의 일부이므로 XML을 단순화했습니다. 나는 단순화 된 예제를 직접 테스트하지 않았다. 이 문제를 일으키는 큰 파일이있는 뭔가가 있어야합니다. – Trygve

+0

Duh, 오류 발견 ... Where 절의 "코드"및 "텍스트"요소를 참조 할 때 nsName (네임 스페이스 이름)을 추가하는 것을 잊었습니다. 아마 처음 테스트에서 맞았지만 더 많은 코드를 추가 할 때 나는 그것을 버렸습니다. 다른 곳에서 nsName을 남겨두면 NullReferenceException이 발생하지만 where 절에있는 것은 아닙니다. ... 올바른 방향으로 나를 이끌어 주셔서 고마워요. – Trygve

답변

2

내 의견에 답변되었습니다. 요소 이름 앞에 누락 된 네임 스페이스 이름이있어서 주문이 예상대로 작동하지 않습니다.

+0

이 문제는 저를 생각해 봤고 파일을로드 한 후 xml 노드에서 네임 스페이스 정보를 제거하고 실제로 작업하기 전에 좋은 생각이었을 것이라고 생각합니다. 그런 식으로 테스트 코드와 실제 프로덕션 코드가 동일하게 작동 할 수 있으며 코드의 요소를 참조하기 위해 많은 네임 스페이스 정보를 가질 필요가 없습니다. http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/bed57335-827a-4731-b6da-a7636ac29f21/ 및 http://stackoverflow.com/questions/1145659/ignore-namespaces-in -linq-to-xml. 이견있는 사람? – Trygve