2015-03-19 2 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, объединив их вместе или чего вы пытаетесь достичь? –

+0

Элемент имени отсутствует в первом элементе file и country отсутствует во втором файле, тогда также я получаю значение Country = и Name value =, и если это не означает, что я тоже не должен этого значения использовать и как можно я достигаю этого ?? –

+0

@Thomas Lindvall: Я хочу, чтобы выход имел значение Country = 1 и значение Name = XYZ. –

ответ

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

Спасибо большое :) :) –

0

В следующей части, бросить XElement к string вместо 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

: Спасибо, да, я получил выход и но получаю вывод, как значение по стране = 1 Значение имени = Значение страны = Значение имени = XYZ и как можно удалить эти пустые значения? –

Смежные вопросы