使用属性过滤器读取 XDocument 的后代元素
Posted
技术标签:
【中文标题】使用属性过滤器读取 XDocument 的后代元素【英文标题】:Read descendant element of XDocument with attribute-filter 【发布时间】:2021-12-07 14:04:04 【问题描述】:我将以下 XML 作为 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>
现在我想获取具有特定键-属性-值的后代数据元素的值。我试过了
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();
其中 xdc 是 XDocument。
但我没有电车。有人可以帮助我,我做错了什么吗?谢谢。
【问题讨论】:
【参考方案1】:请尝试以下解决方案。
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);
输出
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:\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());
【讨论】:
以上是关于使用属性过滤器读取 XDocument 的后代元素的主要内容,如果未能解决你的问题,请参考以下文章
使用 XDocument 和 Linq 读取 XML - 检查元素是不是为 NULL?