Home > Blockchain >  Read descendant element of XDocument with attribute-filter
Read descendant element of XDocument with attribute-filter

Time:10-22

I have the following XML loaded as an XDocument:

<?xml version="1.0" encoding="utf-8"?>
<europa3000_BASIC_DATA_CFG>
  <Version>5.0.6.6</Version>
  <Hash>555306</Hash>
  <GROUP Key="Basic_Data1" Pos="1">
    <Data Key="GeneralLedgerInterface" Pos="1">1</Data>
    <Data Key="CollectivePostings" Pos="2">2</Data>
    <Data Key="PostingDate" Pos="3">2</Data>
    <Data Key="PostSalesExpenseNet" Pos="4">1</Data>
    <Data Key="PostCreditNotesNeg" Pos="5">1</Data>
    <Data Key="PostingZeroAmounts" Pos="6">1</Data>
    <Data Key="BankDocumentNo" Pos="7">0</Data>
    <Data Key="AmountRoundingNC" Pos="15">2</Data>
    <Data Key="VATRoundingNC" Pos="17">2</Data>
    <Data Key="PurchasePriceCalcType" Pos="21">1</Data>
    <Data Key="PurchasePriceRounding" Pos="23">2</Data>
    <Data Key="DefaultVATCode" Pos="41">00</Data>
    <Data Key="DefaultInputTaxCode" Pos="42">00</Data>
    <DATA_LIST Key="FlatRateSalesTax" Pos="48">
      <List_Count>0</List_Count>
    </DATA_LIST>
  </GROUP>
  <GROUP Key="M003" Pos="2">
    <Data Key="MultipleWarehouses" Pos="1">0</Data>
    <Data Key="OwnWarehouse" Pos="2">1</Data>
    <Data Key="PassiveWarehous" Pos="6">0</Data>
  </GROUP>
</europa3000_BASIC_DATA_CFG>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Now I want to get a value of a descendant Data-Element which has a specific Key-Attribute-Value. I have tried like

var fieldname = "DefaultVATCode";

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

where xdc is the XDocument.

But I don't get an ele. Can someone help me, what I am doing wrong? Thank you.

CodePudding user response:

Please try the following solution.

c#

void Main()
{
    XDocument xdoc = XDocument.Parse(@"<europa3000_BASIC_DATA_CFG>
        <Version>5.0.6.6</Version>
        <Hash>555306</Hash>
        <GROUP Key='Basic_Data1' Pos='1'>
            <Data Key='GeneralLedgerInterface' Pos='1'>1</Data>
            <Data Key='CollectivePostings' Pos='2'>2</Data>
            <Data Key='PostingDate' Pos='3'>2</Data>
            <Data Key='PostSalesExpenseNet' Pos='4'>1</Data>
            <Data Key='PostCreditNotesNeg' Pos='5'>1</Data>
            <Data Key='PostingZeroAmounts' Pos='6'>1</Data>
            <Data Key='BankDocumentNo' Pos='7'>0</Data>
            <Data Key='AmountRoundingNC' Pos='15'>2</Data>
            <Data Key='VATRoundingNC' Pos='17'>2</Data>
            <Data Key='PurchasePriceCalcType' Pos='21'>1</Data>
            <Data Key='PurchasePriceRounding' Pos='23'>2</Data>
            <Data Key='DefaultVATCode' Pos='41'>00</Data>
            <Data Key='DefaultInputTaxCode' Pos='42'>00</Data>
            <DATA_LIST Key='FlatRateSalesTax' Pos='48'>
                <List_Count>0</List_Count>
            </DATA_LIST>
        </GROUP>
        <GROUP Key='M003' Pos='2'>
            <Data Key='MultipleWarehouses' Pos='1'>0</Data>
            <Data Key='OwnWarehouse' Pos='2'>1</Data>
            <Data Key='PassiveWarehous' Pos='6'>0</Data>
        </GROUP>
    </europa3000_BASIC_DATA_CFG>");

    string fieldname = "DefaultVATCode";

    string pos = xdoc.Descendants("GROUP")
        .Where(x => x.Attribute("Key").Value.Equals("Basic_Data1"))
        .Elements("Data")
        .Where(x => x.Attribute("Key").Value.Equals(fieldname))
        .Attributes("Pos").FirstOrDefault().Value;

    Console.WriteLine("pos={0}", pos);
}

Output

pos=41

CodePudding user response:

I usually use a nested dictionary

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:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, Dictionary<string, string>> dict = doc.Descendants("GROUP")
                .GroupBy(x => (string)x.Attribute("Key"), y => y.Elements("Data")
                    .GroupBy(a => (string)a.Attribute("Key"), b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
        }
    }
}
  • Related