简体   繁体   中英

How do I use linq to check if an element has the correct child in XML C#?

I have some values in my XML as follows:

<?xml version="1.0" encoding="utf-8"?>
<repub>
  <head>
    <title>Title</title>
  </head>
  <body>
    <sec name="sec_1">
      <title>First Title</title>
      <break name="article_1-1">
        <h1>
          <page num="1"/>
          <b>First Heading</b>
        </h1>
        <h2>First Subheading</h2>
        <fig>
          <img src="images/img_1-1.jpg" width="826" height="657" alt=""/>
          <fc>
            <i>Image Caption</i>
          </fc>
        </fig>
        <fig>
          <cr>This is a credit</cr>
        </fig>
      </break>
      </sec>
    <sec name="sec_2">
      <title>Second Title</title>
      <break name="article_2-1">
        <h1>
          <page num="2"/>
          <b>Second Heading</b>
        </h1>
        <h2>Second Subheading</h2>
        <fig>
          <cr>This is another credit</cr>
        </fig>
      </break>
      </sec>
  </body>
</repub>

What I want is that I want to show the <break name> that contains a <fig> and <fig> does not contain <img src> .

I am doing the following:

var breaklist = xdoc.Descendants("break").ToList();

foreach (var eachbreak in breaklist)
{
    var emptyfig = eachbreak.Descendants("fig").ToList();
    foreach (var eachfig in emptyfig)
    {
        if (eachfig.Descendants("img").Count() == 0
         && eachfig.Descendants("cr").Count() > 0)
        {
            AddMsg("Empty <fig> tag with only credit in: " + eachbreak.Attribute("name").Value);
        }
    }
}

This returns:

Empty <fig> tag with only credit in: article_1-1
Empty <fig> tag with only credit in: article_2-1

It works but I want a linq approach.

Please help.

Regards

1) Xml To Linq Query with Traditional Approach:

var result = (from br in xdoc.Descendants("break")
              from fig in br.Descendants("fig")
              where fig.Descendants("img").Count() == 0 && fig.Descendants("cr").Count() > 0
              select new
              {
                  Message = "Empty <fig> tag with only credit in: " + br.Attribute("name").Value
              }).ToList();

2) Xml To Linq Query with Lambda Approach:

var result = xdoc.Descendants("break")
.SelectMany(br => br.Descendants("fig")
                    .Where(fig => fig.Descendants("img").Count() == 0 && fig.Descendants("cr").Count() > 0)
                    .Select(x => new
                    {
                         Message = "Empty <fig> tag with only credit in: " + br.Attribute("name").Value
                    })
                    ).ToList();

Print the result to console from both above result

foreach (var message in result)
{
     Console.WriteLine(message.Message);
}

In your case, you can use it with AddMsg like,

foreach (var message in result)
{
    AddMsg(message.Message);
} 

Output:

在此处输入图片说明

Something like this:

string xml = @"<?xml version=""1.0"" encoding=""ISO-8859-1"" standalone=""yes""?>
                <repub>
            <head>
            <title>Title</title>
            </head>
            <body>
            <sec name = ""sec_1"">
                <title> First Title </title>
                <break name = ""article_1-1"">
                <h1><page num = ""1"" /><b> First Heading </b></h1>
                <h2> First Subheading </h2>
                <fig>
                    <img src = ""images/img_1-1.jpg"" width = ""826"" height = ""657"" alt = """" />
                    <fc><i> Image Caption </i></fc>
                </fig>
                <fig><cr> This is a credit </cr></fig>
                </break>
            </sec>
                         </body>
            </repub>";

XDocument xdoc = XDocument.Parse(xml);

var figs = xdoc
            .Descendants("fig").Where(x => (x.Element("img") == null && x.Element("cr") != null))
            .Select(x =>x.Parent.Attribute("name").Value);

foreach (var message in figs)
{
    Console.WriteLine("Empty <fig> tag with only credit in: {0}", message);
}

More on parent and descendant here:

https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xobject.parent?view=netframework-4.7.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM