Получение узла XML с использованием LINQ - PullRequest
2 голосов
/ 25 марта 2010

Почему-то, используя 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 ничего мне не дает. Я думаю, что параметры внутри узлов портят это ..

Как мне получить этот "cuf" с linq?
Что если бы я хотел параметр Id в infNFe?

- [EDIT] -

Я забыл дать «глупый URL в начале», так получилось, что это NAMESPACE (неотказано отображение пространства имен 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;

Есть ли способ установить пространство имен где-нибудь, и нет необходимости помещать его в каждый вызов поля?

Ответы [ 6 ]

3 голосов
/ 25 марта 2010

Вам не нужен этот полный запрос 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 голос
/ 25 марта 2010

Вы смотрите на document.Descendants, который является всеми элементами внутри корня.

document. Потомки в вашем случае будут содержать infNFe, ide, cUF ... вот почему вы не можете найти корень в коллекции.

Попробуйте использовать document.Root.

0 голосов
/ 25 марта 2010

edit: использовать 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") не существует. Вам нужно опросить элемент b с пространством имен namespace. Так же, как пространства имен где-либо еще в C # - это что-то вроде измерений. Вы смотрите на правильном пути, но в неправильном измерении.

0 голосов
/ 25 марта 2010

На самом деле, при запуске вашего кода я не вижу никаких проблем. Я сделал следующее:

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 голосов
/ 25 марта 2010

попробуй query.SingleOrDefault();

0 голосов
/ 25 марта 2010

Вы можете использовать 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...