Getting an XML node using LINQ
Somehow, using linq I can't test it with this CUF field in the beginning:
<NFe>
<infNFe versao="1.0" Id="NFe0000000000">
<ide>
<cUF>35</cUF>
<!--...-->
</ide>
</infNFe>
</NFe>
With the following code:
XDocument document = XDocument.Load(@"c:\nota.xml");
var query = fro开发者_JS百科m NFe in document.Descendants("NFe")
select new
{
cuf = NFe.Element("infNFe").Element("ide").Element("cUF").Value
};
The whole XML loads into document (checked) but NFe.cuf gives me nothing. I guess the parameters inside the nodes are messing it up..
How do I get this "cuf" with linq?
What if I wanted the Id parameter in infNFe ?--[EDIT]--
I had forgotten to give the "silly url in the beginning", what happens is that it is the NAMESPACE, (the non-displaying of the namespace of the xml in Firefox contributed)
Now this works:
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;
Is there a way to set the namespace somewhere, and not needing to put it in every single field call ?
You don't really need that full LINQ query - a single one-liner will do:
string cuf = document.Root.Element("infNFe").Element("ide").Element("cUF").Value;
// cuf = 35
The same for the ID:
string id = document.Root.Element("infNFe").Attribute("Id").Value;
// id = NFe0000000000
You're looking at document.Descendants, which is all the elements inside the root.
document.Descendants in your case would contain infNFe, ide, cUF ... which is why you cannot find the root in the collection.
Try using document.Root instead.
try query.SingleOrDefault();
You could use 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);
}
}
}
}
given this XML:
<?xml version="1.0"?>
<NFe>
<infNFe versao="1.0" Id="NFe0000000000">
<ide>
<cUF>35</cUF>
</ide>
</infNFe>
</NFe>
Actually, when running your code I don't see any problem. I've done the 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);
Given the following xml:
<NFe>
<infNFe versao="1.0" Id="NFe0000000000">
<ide>
<cUF>35</cUF>
</ide>
</infNFe>
</NFe>
It outputs:
35 NFe0000000000
edit: Use an XElement, it's much easier.
Now you're using namespaces, so you need to specify those too with XNamespace
If you aren't sure where it's breaking, simply split your query into multiple lines like the below so that you can step through and determine where the error is occurring.
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;
To clarify the namespace issue, if you have XML like
<a xmlns="namespace">
<b>123</b>
</a>
then a.Element("b")
doesn't exist. You need to interrogate the element b with namespace namespace
. Just like namespaces anywhere else in C# - they are something like dimensions. You are looking in the right path but in the wrong dimension.
精彩评论