2011-09-20 134 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