2010-03-25 73 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