2012-02-02 66 views
2

我想寫一塊接收的字符串編碼,採用數據在此字符串進行修改,另一個字符串然後保存另一個字符串的LINQ to XML比較字符串

我寧願做這使用linq,因爲我對它有點熟悉,但這並不是說我完全密切注視。

無論如何,正在接收的字符串是在像

"<?xml version=\"1.0\" encoding=\"utf-8\"?><Root><Value><Code>AAA</Code><Description>First description</Description><Bool>Y</Bool></Value><Value><Code>BBB</Code><Description>Second description</Description><Bool>Y</Bool></Value><Value><Code>CCC</Code><Description>Third description</Description><Bool>N</Bool></Value></Root>"; 

形式或以適當的格式

"<?xml version=\"1.0\" encoding=\"utf-8\"?> 
    <Root> 
     <Value> 
      <Code>AAA</Code> 
      <Description>First description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>BBB</Code> 
      <Description>Second description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>CCC</Code> 
      <Description>Third description</Description> 
      <Bool>N</Bool> 
     </Value> 
    </Root>" 

,例如。另值喜歡

"<?xml version=\"1.0\" encoding=\"utf-8\"?> 
    <Root> 
     <Value> 
      <Code>111</Code> 
      <Description>111 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>AAA</Code> 
      <Description>First description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>222</Code> 
      <Description>222 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>BBB</Code> 
      <Description>Second description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>333</Code> 
      <Description>333 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>CCC</Code> 
      <Description>Third description</Description> 
      <Bool>Y</Bool> 
     </Value> 
    </Root>" 

所以相同的形式,但更多的價值,並設置爲Y.所有BOOLS所有我想要做的是找到所有與布爾設置爲n的代碼和設置這些BOOLS在新的XML N.

所以結合這兩種的結果將是新的XML但代碼CCC值將有布爾設置爲N.這樣:

"<?xml version=\"1.0\" encoding=\"utf-8\"?> 
    <Root> 
     <Value> 
      <Code>111</Code> 
      <Description>111 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>AAA</Code> 
      <Description>First description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>222</Code> 
      <Description>222 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>BBB</Code> 
      <Description>Second description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>333</Code> 
      <Description>333 description</Description> 
      <Bool>Y</Bool> 
     </Value> 
     <Value> 
      <Code>CCC</Code> 
      <Description>Third description</Description> 
      <Bool>N</Bool> 
     </Value> 
    </Root>" 

對我來說,似乎應該有一個令人難以置信的簡單的方法來使用Linq到XML來做到這一點,但我一直在努力它已經有一段時間了,我對XML的經驗似乎不足,因爲我在這方面遇到了一些麻煩。

任何幫助將不勝感激。

謝謝

+0

xpath比linq更容易xml。它的用戶選擇器類似於jquery – Bonshington 2012-02-02 08:45:48

+1

LINQ to XML,從MSDN上的基礎開始http://msdn.microsoft.com/en-us/library/bb387098.aspx – Lloyd 2012-02-02 09:00:04

回答

2

這樣的事情?

using System.Linq; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static XElement Join(XElement xmlOne, XElement xmlTwo) 
     { 
      return new XElement(
       "Root", 
        xmlOne.Elements("Value").Concat(xmlTwo.Elements("Value")).GroupBy(element => element.Element("Code").Value).Select(
         group => 
          new XElement("Value", 
           new XElement("Code", group.First().Element("Code").Value), 
           new XElement("Description", group.First().Element("Description").Value), 
           new XElement("Bool", group.Any(elem => elem.Element("Bool").Value == "N") ? "N" : "Y"))).ToArray()); 

     } 

     static void Main(string[] args) 
     { 
      var xmlOne = XElement.Parse("<?xml version=\"1.0\" encoding=\"utf-8\"?> <Root>  <Value>   <Code>AAA</Code>   <Description>First description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>BBB</Code>   <Description>Second description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>CCC</Code>   <Description>Third description</Description>   <Bool>N</Bool>  </Value> </Root>"); 
      var xmlTwo = XElement.Parse("<?xml version=\"1.0\" encoding=\"utf-8\"?> <Root>  <Value>   <Code>111</Code>   <Description>111 description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>AAA</Code>   <Description>First description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>222</Code>   <Description>222 description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>BBB</Code>   <Description>Second description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>333</Code>   <Description>333 description</Description>   <Bool>Y</Bool>  </Value>  <Value>   <Code>CCC</Code>   <Description>Third description</Description>   <Bool>Y</Bool>  </Value> </Root>"); 
      var result = Join(xmlOne, xmlTwo); 
     } 
    } 
} 
+0

完美,我只需要添加「var xmlDocument = new XDocument (新的XDeclaration(「1.0」,「utf-8」,null),新的XElement(「使其保持聲明,否則這是完美的解決方案。 – user360968 2012-02-02 22:38:45

0

這裏是另一個解決方案,但它更像是在使用LINQ,而不是使用LINQ做它:

string srcString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Root><Value><Code>AAA</Code><Description>First description</Description><Bool>Y</Bool></Value><Value><Code>BBB</Code><Description>Second description</Description><Bool>Y</Bool></Value><Value><Code>CCC</Code><Description>Third description</Description><Bool>N</Bool></Value></Root>"; 
string targetString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Root><Value><Code>111</Code><Description>111 description</Description><Bool>Y</Bool></Value><Value><Code>AAA</Code><Description>First description</Description><Bool>Y</Bool></Value><Value><Code>222</Code><Description>222 description</Description><Bool>Y</Bool></Value><Value><Code>BBB</Code><Description>Second description</Description><Bool>Y</Bool></Value><Value><Code>333</Code><Description>333 description</Description><Bool>Y</Bool></Value><Value><Code>CCC</Code><Description>Third description</Description><Bool>Y</Bool></Value></Root>"; 

XDocument srcDocument = XDocument.Parse(srcString); 
XDocument targetDocument = XDocument.Parse(targetString); 

// find all Value-elements with Bool = 'N' from the srcString 
var srcData = from data in srcDocument.Element("Root").Elements("Value") 
       where string.Compare(data.Element("Bool").Value.ToString(), "N", true) == 0 
       select new { Code = data.Element("Code").Value, 
          Description = data.Element("Description").Value, 
          Bool = data.Element("Bool").Value }; 

foreach(var item in srcData) 
{ 
    var xmlData = from data in targetDocument.Element("Root").Elements("Value") 
        where string.Compare(data.Element("Code").Value.ToString(), item.Code, true) == 0 
        select data; 

    foreach(var data in xmlData) 
    { 
     data.Element("Bool").Value = "N"; 
    } 
} 

var finalString = targetDocument.ToString(); 
0

如果你的第一個XML存儲在「doc1.xml」,第二個存儲在「doc2.xml」,就可以實現你的目標僅僅通過這樣做:

XElement doc1 = XElement.Load("doc1.xml"); 
XElement doc2 = XElement.Load("doc2.xml"); 

var pairs = from v1 in doc1.Elements("Value") 
    join v2 in doc2.Elements("Value") 
    on v1.Element("Code").Value equals v2.Element("Code").Value 
    select new {v1, v2}; 

foreach (var pair in pairs) 
    pair.v1.Element("Bool").Value = pair.v2.Element("Bool").Value; 

上面的代碼,基於doc2操縱doc1。然後,您可以將結果保存在一個新文件(如「doc3.xml」)中:

doc1.Save("doc3.xml");