Linq to XML 比较字符串

发布于 2025-01-01 21:26:15 字数 4206 浏览 1 评论 0原文

我正在尝试编写一段接收字符串的代码,使用该字符串中的数据对另一个字符串进行更改,然后保存另一个字符串

我更喜欢使用 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。我想要做的就是找到布尔值设置为 N 的所有代码,并将新 XML 上的这些布尔值设置为 N。

因此,将这两者组合起来的结果将是新的 xml,但代码 CCC 的值会将 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 缺乏经验,因为我在这方面遇到了很多麻烦。

任何帮助将不胜感激。

谢谢

I'm trying to write a piece of code which receives a string, uses the data in this string to make changes to another string then saves the other string

I would prefer to do this using linq as I'm somewhat familiar with it, although that's not to say that I'm completely close minded.

Anyway, the string being received is in a form like

"<?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>";

or with proper formatting

    "<?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>"

and, for example. the other value is like

    "<?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>"

so of the same form but with more values and with all Bools set to Y. All I want to do is to find all the codes with a bool set to N and set those Bools on the new XML to N.

so the result of combining both of these would be the new xml but the Value with code CCC would have the Bool set as N. so:

    "<?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>"

To me it seems as though there should be an incredibly easy way to do this using Linq to XML but I've been working at it for a while now and my inexperience with XML seems to be showing as I'm having quite a bit of trouble with this.

Any help would be much appreciated.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

机场等船 2025-01-08 21:26:15

类似的事情?

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);
        }
    }
}

Something like that?

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);
        }
    }
}
梦屿孤独相伴 2025-01-08 21:26:15

这是另一个解决方案,但它更像是使用 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( );

Here is another solution but its more like using linq and not doing it with 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( );
踏月而来 2025-01-08 21:26:15

如果您的第一个 xml 存储在“doc1.xml”中,第二个 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");

If your first xml is stored in "doc1.xml" and the second one is stored in "doc2.xml", you can achieve your goal simply by doing this:

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;

The above code, manipulates doc1 based on doc2. You can then save the result in a new file like "doc3.xml":

doc1.Save("doc3.xml");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文