2010-03-25 87 views
2

不知怎的,一个XML节点,使用LINQ我不能在一开始这个领域CUF测试:获得使用LINQ

<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没有给我什么。我猜节点内部的参数搞乱了它。

如何获得这个“cuf”与linq?
如果我想要infNFe中的Id参数,该怎么办?

- [编辑] -

我忘了给“一开始傻URL”,什么情况是,它是命名空间(的命名空间的非显示XML在Firefox贡献)

现在这个工程:

 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; 

有没有办法在某处设置的命名空间,并且不需要把它在任何一个领域的呼叫?

+0

您没有发布有效的XML(缺少'',''和'')。看起来像一个愚蠢的请求,但看着它(非缩进)使人们认为他们都是根。 – 2010-03-25 12:40:18

+0

@Alex - 编辑XML以使其更清晰。 – 2010-03-25 12:41:23

+0

嗯,我确实提到这是我的XML的开始,并且寻址一个节点只需要名称和父节点,我只想显示它是什么样的,而不是给出有效的XML。 – Marcelo 2010-03-25 12:45:59

回答

3

你并不真正需要的是完整的LINQ查询 - 单个一邮轮将做到:

​​

同为ID:

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

同意,这真的不是一个很好的使用LINQ。 – Nix 2010-03-25 12:59:48

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> 
1

您现在看到的document.Descendants,这是根本中的所有元素。

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

请尝试使用document.Root代替。

+0

在查询中就地使用document.Root是不可能的,因为它返回单个节点,而Descendants返回一个集合的节点。然而,OP可以使用document.Root和单行代码,正如我在答案中所演示的那样。 – 2010-03-25 12:46:51

+0

好点,我想我没有exapnd你将如何使用document.Root – 2010-03-25 13:23:12

0

其实,当运行你的代码时,我没有看到任何问题。 我已经做了follwing:

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 
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#中其他任何地方的命名空间 - 它们就像维度一样。您正在寻找正确的道路,但方向不正确。

+0

嗯,它的工作,但我必须把nd +“领域”每次我打电话给领域?我不可以在哪里安装一个传统的单行命名空间的地方?顺便说一句,谢谢 – Marcelo 2010-03-25 13:24:40

+0

当我第一次开始使用LINQ和XML时,我问了一个类似的问题,但实际上这种方式很有意义。根据我的经验,您总是需要指定名称空间。这没什么大不了的。 – 2010-03-25 13:30:27

+0

*莫名其妙* ..是的..检查新的编辑。我已经用给定的ns +字段创建了单行代码..看起来不错,因为它只是一个函数。 – Marcelo 2010-03-25 13:56:53