2011-09-20 111 views
1

我有一个XML文件,其中的一部分是GoodsItems元素。我想订购GoodsItem元素,以便具有子元素SupplementaryInformationLines.SupplementaryInformationLine,Code == "X002"Text != "NLR"的元素排在第一位。随后所有元素都必须按GoodsItem.TaricCode元素排序。Linq到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时出现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文件保存的顺序,我只是做在内存中的排序。尽管使用ReplaceNode approach而不是linq查询也可能是一个解决方案,但我只需要让这个工作起作用。

+0

该代码看起来不错,并且该xml的一个最小示例,并且该查询返回首先按要求排序的第一个元素。 – AakashM

+0

嗯,那应该会让我领先。 GoodsItems是更大的xml文件的一部分,我简化了xml。我自己并没有真正测试这个简化的例子。导致这种行为的大文件必须有一些东西。 – Trygve

+0

Duh,我发现这个错误...当我引用where子句中的“Code”和“Text”元素时,我忘了添加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到XML。有什么想法吗? – Trygve