Считайте элемент-потомок XDocument с атрибутом-фильтром

#c# #xml #linq-to-xml

Вопрос:

У меня есть следующий XML-файл, загруженный в качестве XDocument:

 lt;?xml version="1.0" encoding="utf-8"?gt; lt;europa3000_BASIC_DATA_CFGgt;  lt;Versiongt;5.0.6.6lt;/Versiongt;  lt;Hashgt;555306lt;/Hashgt;  lt;GROUP Key="Basic_Data1" Pos="1"gt;  lt;Data Key="GeneralLedgerInterface" Pos="1"gt;1lt;/Datagt;  lt;Data Key="CollectivePostings" Pos="2"gt;2lt;/Datagt;  lt;Data Key="PostingDate" Pos="3"gt;2lt;/Datagt;  lt;Data Key="PostSalesExpenseNet" Pos="4"gt;1lt;/Datagt;  lt;Data Key="PostCreditNotesNeg" Pos="5"gt;1lt;/Datagt;  lt;Data Key="PostingZeroAmounts" Pos="6"gt;1lt;/Datagt;  lt;Data Key="BankDocumentNo" Pos="7"gt;0lt;/Datagt;  lt;Data Key="AmountRoundingNC" Pos="15"gt;2lt;/Datagt;  lt;Data Key="VATRoundingNC" Pos="17"gt;2lt;/Datagt;  lt;Data Key="PurchasePriceCalcType" Pos="21"gt;1lt;/Datagt;  lt;Data Key="PurchasePriceRounding" Pos="23"gt;2lt;/Datagt;  lt;Data Key="DefaultVATCode" Pos="41"gt;00lt;/Datagt;  lt;Data Key="DefaultInputTaxCode" Pos="42"gt;00lt;/Datagt;  lt;DATA_LIST Key="FlatRateSalesTax" Pos="48"gt;  lt;List_Countgt;0lt;/List_Countgt;  lt;/DATA_LISTgt;  lt;/GROUPgt;  lt;GROUP Key="M003" Pos="2"gt;  lt;Data Key="MultipleWarehouses" Pos="1"gt;0lt;/Datagt;  lt;Data Key="OwnWarehouse" Pos="2"gt;1lt;/Datagt;  lt;Data Key="PassiveWarehous" Pos="6"gt;0lt;/Datagt;  lt;/GROUPgt; lt;/europa3000_BASIC_DATA_CFGgt; 

Теперь я хочу получить значение элемента данных-потомка, который имеет определенное значение атрибута-Ключа. Я пробовал, как

 var fieldname = "DefaultVATCode";  var ele = xdc.Descendants("europa3000_BASIC_DATA_CFG").Where(x =gt; (string) x.Attribute("Key") == "Basic_Data1").Where(x =gt; (string) x.Attribute("Key") == fieldname).FirstOrDefault();  

где xdc-это XDocument.

Но я не получаю эля. Кто-нибудь может мне помочь, что я делаю не так? Спасибо.

Ответ №1:

Пожалуйста, попробуйте следующее решение.

c#

 void Main() {  XDocument xdoc = XDocument.Parse(@"lt;europa3000_BASIC_DATA_CFGgt;  lt;Versiongt;5.0.6.6lt;/Versiongt;  lt;Hashgt;555306lt;/Hashgt;  lt;GROUP Key='Basic_Data1' Pos='1'gt;  lt;Data Key='GeneralLedgerInterface' Pos='1'gt;1lt;/Datagt;  lt;Data Key='CollectivePostings' Pos='2'gt;2lt;/Datagt;  lt;Data Key='PostingDate' Pos='3'gt;2lt;/Datagt;  lt;Data Key='PostSalesExpenseNet' Pos='4'gt;1lt;/Datagt;  lt;Data Key='PostCreditNotesNeg' Pos='5'gt;1lt;/Datagt;  lt;Data Key='PostingZeroAmounts' Pos='6'gt;1lt;/Datagt;  lt;Data Key='BankDocumentNo' Pos='7'gt;0lt;/Datagt;  lt;Data Key='AmountRoundingNC' Pos='15'gt;2lt;/Datagt;  lt;Data Key='VATRoundingNC' Pos='17'gt;2lt;/Datagt;  lt;Data Key='PurchasePriceCalcType' Pos='21'gt;1lt;/Datagt;  lt;Data Key='PurchasePriceRounding' Pos='23'gt;2lt;/Datagt;  lt;Data Key='DefaultVATCode' Pos='41'gt;00lt;/Datagt;  lt;Data Key='DefaultInputTaxCode' Pos='42'gt;00lt;/Datagt;  lt;DATA_LIST Key='FlatRateSalesTax' Pos='48'gt;  lt;List_Countgt;0lt;/List_Countgt;  lt;/DATA_LISTgt;  lt;/GROUPgt;  lt;GROUP Key='M003' Pos='2'gt;  lt;Data Key='MultipleWarehouses' Pos='1'gt;0lt;/Datagt;  lt;Data Key='OwnWarehouse' Pos='2'gt;1lt;/Datagt;  lt;Data Key='PassiveWarehous' Pos='6'gt;0lt;/Datagt;  lt;/GROUPgt;  lt;/europa3000_BASIC_DATA_CFGgt;");   string fieldname = "DefaultVATCode";   string pos = xdoc.Descendants("GROUP")  .Where(x =gt; x.Attribute("Key").Value.Equals("Basic_Data1"))  .Elements("Data")  .Where(x =gt; x.Attribute("Key").Value.Equals(fieldname))  .Attributes("Pos").FirstOrDefault().Value;   Console.WriteLine("pos={0}", pos); }  

Выход

 pos=41  

Ответ №2:

Я обычно использую вложенный словарь

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Linq;  namespace ConsoleApplication4 {  class Program  {  const string FILENAME = @"c:temptest.xml";  static void Main(string[] args)  {  XDocument doc = XDocument.Load(FILENAME);   Dictionarylt;string, Dictionarylt;string, stringgt;gt; dict = doc.Descendants("GROUP")  .GroupBy(x =gt; (string)x.Attribute("Key"), y =gt; y.Elements("Data")  .GroupBy(a =gt; (string)a.Attribute("Key"), b =gt; (string)b)  .ToDictionary(a =gt; a.Key, b =gt; b.FirstOrDefault()))  .ToDictionary(x =gt; x.Key, y =gt; y.FirstOrDefault());  }  } }