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.