#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()); } } }