2010-07-26 115 views
2

我有一個XML映射文件,它看起來像這樣的LINQ to XML,選擇一個給定節點的所有屬性和值

<colourMappings> 
    <model name="modelX"> 
     <mapping colour="White" configCode="1"></mapping> 
     <mapping colour="Aluminium" configCode="2"></mapping> 
     <mapping colour="Black" configCode="3"></mapping> 
     <mapping colour="Blue" configCode="4"></mapping> 
     <mapping colour="White Pearl" configCode="5"></mapping> 
     <mapping colour="Graphite" configCode="6"></mapping> 
     <mapping colour="Gunmetal" configCode="7"></mapping> 
     <mapping colour="Indigo" configCode="8"></mapping> 
     <mapping colour="Red" configCode="9"></mapping> 
    </model> 
    <model name="modelY"> 
     <mapping colour="White" configCode="1" stConfigCode= "xx" dgConfigCode="hj"></mapping> 
     <mapping colour="Aluminium" configCode="2" stConfigCode= "xy" dgConfigCode="gh"></mapping> 
     <mapping colour="Black" configCode="3" stConfigCode= "xt" dgConfigCode="fg"></mapping> 
     <mapping colour="Blue" configCode="4" stConfigCode= "sd" dgConfigCode="fg"></mapping> 
     <mapping colour="White Pearl" configCode="5" stConfigCode= "df" dgConfigCode="df"></mapping> 
     <mapping colour="Graphite" configCode="6" stConfigCode= "xc" dgConfigCode="df"></mapping> 
     <mapping colour="Gunmetal" configCode="7" stConfigCode= "cv" dgConfigCode="cv"></mapping> 
     <mapping colour="Indigo" configCode="8" stConfigCode= "zx" dgConfigCode="vb"></mapping> 
     <mapping colour="Red" configCode="9" stConfigCode= "fg" dgConfigCode="cv"></mapping> 
    </model> 
</colourMappings> 

我希望能夠拉出來的所有屬性,並給出它們的值型號名稱和顏色

eg鑑於ModelY和白色

,我想獲得configCode = 「1」 stConfigCode = 「XX」 dgConfigCode = 「HJ」 這可能是在任何結構 - 數組,列表,無論

我一直使用Linq to XML但無法獲得正確的語法

XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml"); 
var q = from c in mappings.Descendants("model") 
        where (string)c.Attribute("name") == "modelY" && (string)c.Descendants("mapping").Attributes("colour").FirstOrDefault() == "White" 
        select c.Attributes(); 

任何人都知道如何做到這一點?

樂於使用任何方法,並不一定需要的LINQ

回答

5

更新

的方法歸納爲:

public IEnumerable<XAttribute> GetAttributes(string modelName, string colour) 
{ 
    XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml"); 

    var q1 = 
     from elm in mappings.Descendants("model") 
     where (string)elm.Attribute("name") == "modelY" 
     select elm; 

    var q2 = 
     from elm in q1.Descendants("mapping") 
     where (string)elm.Attribute("colour") == "White" 
     select elm.Attributes().Where(a => a.Name != "colour"); 


    foreach (IEnumerable<XAttribute> attributeList in q2) 
    { 
     foreach (XAttribute attribute in attributeList) 
     { 
      yield return attribute; 
     } 
    } 
} 
+0

謝謝 - 這不完全是我需要的。你的一個返回每個映射的所有屬性 我只想要ModelY中單個映射的屬性具有白色 Decierded做它作爲2階段查詢 - 見下面 – ChrisCa 2010-07-26 10:38:39

+0

@Christo毛皮:對不起,我的錯誤,只是更新了代碼,所以它應該現在工作:) – 2010-07-26 10:54:27

+0

謝謝 - 我得出了同樣的結論,你做了2步 – ChrisCa 2010-07-26 10:56:48

1

,因爲我時間緊迫,我會用一個2階段的過程

但會有興趣聽到這是否可能在一個查詢

var matchingModelXml = from c in mappings.Descendants("model") 
           where (string)c.Attribute("name") == "modelY" 
           select c; 

var mappingAttributes = from b in matchingModelXml.Descendants("mapping") 
         where (string)b.Attribute("colour") == "White" 
         select b.Attributes(); 
1

只是因爲我喜歡挑戰,在這裏它是在一個查詢:

XDocument test = XDocument.Parse("<colourMappings> <model name=\"modelX\">  <mapping colour=\"White\" configCode=\"1\"></mapping>  <mapping colour=\"Aluminium\" configCode=\"2\"></mapping>  <mapping colour=\"Black\" configCode=\"3\"></mapping>  <mapping colour=\"Blue\" configCode=\"4\"></mapping>  <mapping colour=\"White Pearl\" configCode=\"5\"></mapping>  <mapping colour=\"Graphite\" configCode=\"6\"></mapping>  <mapping colour=\"Gunmetal\" configCode=\"7\"></mapping>  <mapping colour=\"Indigo\" configCode=\"8\"></mapping>  <mapping colour=\"Red\" configCode=\"9\"></mapping> </model> <model name=\"modelY\">  <mapping colour=\"White\" configCode=\"1\" stConfigCode= \"xx\" dgConfigCode=\"hj\"></mapping>  <mapping colour=\"Aluminium\" configCode=\"2\" stConfigCode= \"xy\" dgConfigCode=\"gh\"></mapping>  <mapping colour=\"Black\" configCode=\"3\" stConfigCode= \"xt\" dgConfigCode=\"fg\"></mapping>  <mapping colour=\"Blue\" configCode=\"4\" stConfigCode= \"sd\" dgConfigCode=\"fg\"></mapping>  <mapping colour=\"White Pearl\" configCode=\"5\" stConfigCode= \"df\" dgConfigCode=\"df\"></mapping>  <mapping colour=\"Graphite\" configCode=\"6\" stConfigCode= \"xc\" dgConfigCode=\"df\"></mapping>  <mapping colour=\"Gunmetal\" configCode=\"7\" stConfigCode= \"cv\" dgConfigCode=\"cv\"></mapping>  <mapping colour=\"Indigo\" configCode=\"8\" stConfigCode= \"zx\" dgConfigCode=\"vb\"></mapping>  <mapping colour=\"Red\" configCode=\"9\" stConfigCode= \"fg\" dgConfigCode=\"cv\"></mapping> </model></colourMappings>"); 

var maps = from model in test.Root.Elements("model") 
      from attr in model.Attributes("name") 
      from mapping in model.Elements("mapping") 
      where attr.Value == "modelY" && mapping.Attribute("colour").Value == "White" 
      select new 
      { 
       configCode = mapping.Attribute("configCode").Value 
       , stConfigCode = mapping.Attribute("stConfigCode").Value 
       , dgConfigCode = mapping.Attribute("dgConfigCode").Value 
      }; 

foreach (var map in maps) 
{ 
    Console.Write("configCode: "); 
    Console.WriteLine(map.configCode); 
    Console.Write("stConfigCode: "); 
    Console.WriteLine(map.stConfigCode); 
    Console.Write("dgConfigCode: "); 
    Console.WriteLine(map.dgConfigCode); 
} 
+0

尼斯:)只需要刪除屬性「顏色」,但多數民衆贊成在這方面:) – 2010-07-26 17:13:00

+0

只做了一些時間,似乎你的單個查詢是在這個小樣本集慢50-60%。我認爲原因在於那些4「來自」的結果經過了很多枚舉。但仍然是一個很好的查詢:) – 2010-07-26 18:44:46

+0

謝謝。我可能應該提到我只寫這個爲樂趣。我也會去兩條查詢路線。它更容易閱讀以及更快:) – 2010-07-27 06:12:18

0

我現在知道這是古老的,但我認爲沒有比neccessary外觀做更多的處理的方式來解決這個問題是這樣的:

mappings.Root.Elements() 
     .Where(cm => cm.Attribute("name").Value == "modelY") 
     .SelectMany(cm => cm.Elements() 
          .Where(m => m.Attribute("colour").Value == "White") 
          .SelectMany(m => m.Attributes())); 

在查詢格式,這將是:

from cm in doc.Root.Elements() 
where cm.Attribute("name").Value == "modelY" 
from m in cm.Elements() 
where m.Attribute("colour").Value == "White" 
from att in m.Attributes() 
select att;