2015-03-19 59 views
0

我需要幫助檢索第一個文件中的元素國家及其值1,第二個文件中的元素名稱及其值XYZ。Linq to xml [其中節點存在於一個文件中而不存在於另一個文件中]

我正在接受來自app.config的輸入,並且我存儲的這兩個文件都是C:\ Test \和文件。

sample.xml中

<?xml version="1.0" encoding="utf-8"?> 
<env:Contentname xmlns:env="http://data.schemas" xmlns="http://2013-02-01/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <env:Body> 
     <env:Content action="Hello"> 
     <env:Data xsi:type="Yellow"> 
     </env:Data> 
     </env:Content> 

     <env:Content action="Hello"> 
     <env:Data xsi:type="Red"> 
      <Status xmlns="http://2010-10-10/"> 
      <Id >39681</Id> 
      <Name>Published</Name> 
      </Status> 
     </env:Data> 
     </env:Content> 

     <env:Content action="Hello"> 
     <env:Data xsi:type="green"> 
      <Document> 
      <country>1</country> 
      </Document> 
     </env:Data> 
     </env:Content> 
    </env:Body> 
</env:Contentname> 

和我的第二個文件是Sample1.xml

<?xml version="1.0" encoding="utf-8"?> 
<env:Contentname xmlns:env="http://data.schemas" xmlns="http://2013-02-01/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <env:Body> 
     <env:Content action="Hello"> 
     <env:Data xsi:type="Yellow"> 
     </env:Data> 
     </env:Content> 

     <env:Content action="Hello"> 
     <env:Data xsi:type="Red"> 
      <Status xmlns="http://2010-10-10/"> 
      <Id >39681</Id> 
      <Name>Published</Name> 
      </Status> 
     </env:Data> 
     </env:Content> 

     <env:Content action="Hello"> 
     <env:Data xsi:type="green"> 
      <Document> 
      <Name>XYZ</Name> 
      </Document> 
     </env:Data> 
     </env:Content> 
    </env:Body> 
</env:Contentname> 

我想這一點,

using System; 
using System.Collections.Generic; 
using System.Xml.Linq; 
using System.Linq; 
using System.Configuration; 
using System.IO; 

namespace LinEx 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     String ReadFile = System.Configuration.ConfigurationManager.AppSettings["Check"]; 

     DirectoryInfo di = new DirectoryInfo(ReadFile); 

     FileInfo[] rgFiles = di.GetFiles("*.xml"); 
     foreach (FileInfo fi in rgFiles) 
     { 
      XElement root = XElement.Load(fi.FullName); 
      XNamespace aw = "http://data.schemas"; 
      XNamespace kw = "http://www.w3.org/2001/XMLSchema-instance"; 
      XNamespace ns = "http://2013-02-01/"; 


      var result = from x in root.Descendants(aw + "Content") 
         where (string)x.Attribute("action") == "Hello" 
         from y in x.Descendants(aw + "Data") 
         where (string)y.Attribute(kw + "type") == "green" 
         select new 
         { 
          Firstel = y.Element(ns + "Document").Element(ns + "country").Value, 
          Secondel=y.Element(ns+"Document").Element(ns+"Name").Value, 
         }; 

      foreach (var item in result) 
      { 
       Console.WriteLine("Country value={0}", item.Firstel); 
       Console.WriteLine("Name value={0}", item.Secondel); 
      } 
     } 
     Console.ReadLine(); 
     } 
    } 
} 

但我得到錯誤(對象引用未設置到一個對象的實例)。善良幫助我,並提前致謝。

+0

什麼是期望的輸出?您是否想通過將它們連接在一起來修復XML,或者您想要實現什麼功能? – 2015-03-19 07:27:27

+0

姓名元素不存在於第一個文件中,並且country元素不存在於第二個文件中,那麼我也得到了Country Value =和Name value =,如果不存在則意味着我不應該要求這些值,我做到了? – 2015-03-19 07:34:07

+0

@Thomas Lindvall:我希望輸出像Country value = 1和Name value = XYZ。 – 2015-03-19 07:40:07

回答

0

首個解決方案(使用XPath): 你將不得不調整的命名空間,並與你的搭配我的代碼,但這個想法是有:

static void Main(string[] args) 
{ 

    XElement file1 = XElement.Parse(@"<?xml version='1.0' encoding='utf-8'?> 
     <Contentname> 
      <Body> 
       <Content action='Hello'> 
        <Data type='Yellow'> 
        </Data> 
       </Content> 

       <Content action='Hello'> 
        <Data type='Red'> 
        <Status xmlns='http://2010-10-10/'> 
         <Id >39681</Id> 
         <Name>Published</Name> 
        </Status> 
       </Data> 
       </Content> 

       <Content action='Hello'> 
       <Data type='green'> 
        <Document> 
        <country>1</country> 
        </Document> 
       </Data> 
       </Content> 
      </Body> 
     </Contentname>"); 
    XElement file2 = XElement.Parse(@"<?xml version='1.0' encoding='utf-8'?> 
     <Contentname> 
      <Body> 
       <Content action='Hello'> 
        <Data type='Yellow'> 
        </Data> 
       </Content> 

       <Content action='Hello'> 
        <Data type='Red'> 
        <Status xmlns='http://2010-10-10/'> 
         <Id >39681</Id> 
         <Name>Published</Name> 
        </Status> 
       </Data> 
       </Content> 

       <Content action='Hello'> 
       <Data type='green'> 
        <Document> 
        <Name>XYZ</Name> 
        </Document> 
       </Data> 
       </Content> 
      </Body> 
     </Contentname>"); 


    List<XElement> roots = new List<XElement> {file1, file2}; 
    foreach (var root in roots) 
    { 

     var nodesCountry = root.XPathSelectElements("Body/Content[@action='Hello']/Data[@type='green']/Document/country"); 
     var nodesName = root.XPathSelectElements("Body/Content[@action='Hello']/Data[@type='green']/Document/Name"); 


     foreach (var item in nodesName) 
     { 

      Console.WriteLine("Name value={0}", item.Value); 
     } 
     foreach (var item in nodesCountry) 
     { 
      Console.WriteLine("Country value={0}", item.Value); 
     } 
    } 
    Console.ReadLine(); 
} 

解決方法二(用的解決方案@ har07,少乾淨):

select new 
{ 
    Firstel = (string)y.Element(ns + "Document").Element(ns+"country"), 
    Secondel = (string)y.Element(ns+"Document").Element(ns+"Name"), 
}; 

foreach (var item in result){ 
     if(item.Firstel!=string.empty) 
      Console.WriteLine("Country value={0}", item.Firstel); 
     if(item.Secondel!=string.empty) 
      Console.WriteLine("Name value={0}", item.Secondel); 
} 
+0

非常感謝:) :) – 2015-03-19 09:26:11

0

在以下的部分,鑄XElementstring代替acessing Value屬性:

select new 
{ 
    Firstel = (string)y.Element(ns + "Document").Element(ns+"country"), 
    Secondel = (string)y.Element(ns+"Document").Element(ns+"Name"), 
}; 

這將避免的情況下「空引用」異常當任<country>元件或<Name>元件不存在於XML文檔。

+0

:謝謝;是的,我得到了輸出,但m獲得輸出像國家值= 1 名稱值= 國家值= 名稱值= XYZ和如何刪除這些空值? – 2015-03-19 07:07:08

相關問題