C# 使用命名空间和重复节点读取XML

C# 使用命名空间和重复节点读取XML,c#,xml,C#,Xml,我有以下XML: <resource> <description>TTT</description> <title>TEST</title> <entity xmlns="TdmBLRuPlUz.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaL

我有以下XML:

<resource>
  <description>TTT</description>
  <title>TEST</title>
  <entity xmlns="TdmBLRuPlUz.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="TdmBLRuPlUz.xsd TdmBLRuPlUz.xsd">
    <UzdProd>
      <row>
        <F_DAUDZ>50</F_DAUDZ>
        <BR_DAUDZ/>
        <DAUDZ>50</DAUDZ>
        <U_DAUDZ/>
        <NKODS>ST2.0_014_023</NKODS>
      </row>
    </UzdProd>
    <UzdMat>
      <row>
        <NKODS>SAG 2.0_014_150</NKODS>
        <NNOSAUK>Sagatave 2.0mm*0.14*150m</NNOSAUK>
        <PK_VIEN>1</PK_VIEN>
        <DAUDZ>0.077</DAUDZ>
        <F_DAUDZ>0.077</F_DAUDZ>
      </row>
    </UzdMat>
  </entity>
</resource>
我需要的是从XML节点
NKODS
F_DAUDZ
DAUDZ
读取值

问题是,有重复的节点具有这些名称,通过此代码,它将给出
UzdMat
节点下的最后一个节点。在
UzdProd
下获取这些节点值的方法是什么?
我试图将
更改为
UzdProd
,但没有成功。

看看这是否有效:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication25
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement entity = doc.Descendants().Where(x => x.Name.LocalName == "entity").FirstOrDefault();
            XNamespace ns = entity.GetDefaultNamespace();

            var results = entity.Elements().Select(x => new {
                uzd = x.Name.LocalName,
                dict = x.Descendants(ns + "row").Elements().GroupBy(y => y.Name.LocalName, z => (string)z)
                   .ToDictionary(y => y.Key, z => z.FirstOrDefault())
            }).ToList();

        }
    }
}

您需要读取所需的特定行,而不是遍历所有行。例如:

var prodRow = doc.Descendants(ns + "UzdProd").Elements(ns + "row").Single();
var matRow = doc.Descendants(ns + "UzdMat").Elements(ns + "row").Single();

var prodNkods = (string) prodRow.Element(ns + "NKODS");
var matNkods = (string) matRow.Element(ns + "NKODS");

请参阅工作演示。

为了清晰起见,您可以拆分XML和C样本吗(来自评论:)我在您的问题中添加了相关标记
C#
,并格式化了代码部分。您的循环应该运行两次-第一行一次,第二行一次。您是否只需要
UzdProd
中的行的值?稍后,我将需要从UzdProd和UzdMatYour代码(请参阅)中获取这两个值。你到底希望它的输出是什么?当我试图打印那个列表时,我只得到了节点名。如何从我拥有的变量列表中获取值?它是一个包含键和值的字典。并非所有元素都有值,因此您将得到一些空值。要从dict中获取值,可以通过字典枚举,也可以从键中获取值。谢谢但是,如果UzdProd行包含另一个节点,该节点将具有另一个具有NKODS的行,该怎么办?我想它会因为Single()而引发异常?只需提前考虑。@WhizBoy
元素
只查找直接子元素(当子元素是递归的时)。在您建议的情况下,此查询仍然有效,因为
UzdProd
行仍然只有一个
NKODS
子元素。
var prodRow = doc.Descendants(ns + "UzdProd").Elements(ns + "row").Single();
var matRow = doc.Descendants(ns + "UzdMat").Elements(ns + "row").Single();

var prodNkods = (string) prodRow.Element(ns + "NKODS");
var matNkods = (string) matRow.Element(ns + "NKODS");