Linq to XML来比较字符串

时间:2012-02-02 08:35:33

标签: c# string linq 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>"

因此具有相同的形式,但具有更多的值并且所有Bools都设置为Y.我想要做的就是找到bool设置为N的所有代码,并将新XML上的Bools设置为N.

所以将这两者结合起来的结果将是新的xml,但是代码为CCC的Value会将Bool设置为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 to XML来实现这一点,但我已经在这方面工作了一段时间,而我对XML的经验似乎很少,因为我已经相当这有点麻烦。

非常感谢任何帮助。

由于

3 个答案:

答案 0 :(得分: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);
        }
    }
}

答案 1 :(得分: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( );

答案 2 :(得分: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;

上述代码根据doc1操纵doc2。然后,您可以将结果保存在新文件中,例如“doc3.xml”:

doc1.Save("doc3.xml");