2015-03-19 57 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

相关问题