使用LINQ获取XML节点

时间:2010-03-25 12:30:17

标签: c# .net xml linq

不知何故,使用linq我无法在开头用这个CUF字段测试它:

<NFe>
    <infNFe versao="1.0" Id="NFe0000000000">
        <ide>
             <cUF>35</cUF>
             <!--...-->
        </ide>
    </infNFe>
</NFe>

使用以下代码:

XDocument document = XDocument.Load(@"c:\nota.xml");
            var query = from NFe in document.Descendants("NFe")
                        select new
                        {
                            cuf = NFe.Element("infNFe").Element("ide").Element("cUF").Value
                        };

整个XML加载到文档中(已检查)但NFe.cuf没有给我任何东西。我猜节点内的参数搞砸了。

如何使用linq获得此“cuf”? 如果我想在infNFe中使用Id参数怎么办?

- [编辑] -

我忘了在开头给出“愚蠢的网址”,会发生的是NAMESPACE,(在Firefox中没有显示xml的命名空间)

现在可行:

        XNamespace ns = "http://www.portalfiscal.inf.br/nfe";
        XElement root = XElement.Load(@"c:\nota.xml");

        textBox1.Text = root.Element(ns + "infNFe").Element(ns + "ide").Element(ns + "cUF").Value;

有没有办法在某处设置命名空间,而不需要将它放在每个字段调用中?

6 个答案:

答案 0 :(得分:3)

你真的不需要那个完整的LINQ查询 - 只需一个单行程序:

string cuf = document.Root.Element("infNFe").Element("ide").Element("cUF").Value;
// cuf = 35

ID相同:

string id = document.Root.Element("infNFe").Attribute("Id").Value;
// id = NFe0000000000

答案 1 :(得分:1)

您正在查看document.Descendants,它是根目录中的所有元素。

document.Descendants在你的情况下将包含infNFe,ide,cUF ...... 这就是为什么你找不到集合中的根。

请尝试使用document.Root。

答案 2 :(得分:0)

您可以使用XPath:

using System;
using System.Xml.Linq;
using System.Xml.XPath;

class Program
{
    static void Main(string[] args)
    {
        var doc = XDocument.Load(@"c:\nota.xml");
        var cuf = doc.XPathSelectElement("//cUF");
        if (cuf != null)
        {
            Console.WriteLine(cuf.Value);
        }

        var infNFe = doc.XPathSelectElement("//infNFe");
        if (infNFe != null)
        {
            var id = infNFe.Attribute("Id");
            if (id != null) 
            {
                Console.WriteLine(id.Value);
            }
        }

    }
}

给出这个XML:

<?xml version="1.0"?>
<NFe>
  <infNFe versao="1.0" Id="NFe0000000000">
    <ide>
      <cUF>35</cUF>
    </ide>
  </infNFe>
</NFe>

答案 3 :(得分:0)

尝试query.SingleOrDefault();

答案 4 :(得分:0)

实际上,在运行代码时我没有看到任何问题。 我完成了以下操作:

XDocument document = XDocument.Load(@"c:\temp\nota.xml");
var query = from NFe in document.Descendants("NFe")
            select new
            {
                cuf = NFe.Element("infNFe").Element("ide").Element("cUF").Value,
                infId = NFe.Element("infNFe").Attribute("Id").Value
            };

foreach(var v in query)
    Console.WriteLine(v.cuf + " " + v.infId);

给出以下xml:

<NFe> 
<infNFe versao="1.0" Id="NFe0000000000"> 
<ide> 
<cUF>35</cUF> 
</ide>
</infNFe>
</NFe> 

输出:

35 NFe0000000000

答案 5 :(得分:0)

编辑:使用XElement,它更容易。

现在您正在使用名称空间,因此您还需要使用XNamespace

指定名称空间

如果您不确定它在哪里,只需将您的查询拆分为多行,如下所示,以便您可以单步执行并确定错误发生的位置。

XNamespace ns = "http://www.somewebsite.com";
XElement root = XElement.Load(@"c:\nota.xml");
var infNFe = root.Element(ns + "infNFe");
var ide = infNFe.Element(ns + "ide");
var cUF = ide.Element(ns + "cUF");
var value = cUF.Value;

要澄清名称空间问题,如果您有XML

<a xmlns="namespace">
    <b>123</b>
</a>

然后a.Element("b")不存在。您需要使用命名空间namespace查询元素b。就像C#中的其他任何名称空间一样 - 它们就像维度一样。你正在寻找正确的道路,但方向错误。