简体   繁体   中英

Filter XML for specific element value in C#

My xml document looks like:

<Report>
  <id>820</id>
  <number>u_incident_1</number>
  <Entry>
    <findings>1</findings>
    <area>PS</area>
    <section>Section 1</section>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
  </Entry>
  <Entry>
    <findings>2</findings>
    <area>PR</area>
    <section>Section 2</section>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
    <image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
  </Entry>
  <RE_image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</RE_image>
  <RE_image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</RE_image>
</Report>

The goal is to extract <image> elements out of <Entry> element, which has <section>Section 1</section> element as part of it.

So far I was able to extract all images related to <image> element (6 in total), however I find it hard to only return the ones that I need. The code I am using is:

var xmlDocument = XDocument.Load("mypath\Report.xml");
            var reportElement = xmlDocument.Elements().Where(xe => xe.Name.LocalName == "Report").First();
            var allEntries = reportElement.Elements().Where(xe => xe.Name.LocalName == "Entry").ToList();
            var allImages = allEntries.SelectMany(xe => xe.Elements().Where(xz => xz.Name.LocalName == "image"));

            // to show the image values
            foreach (var x in allImages.Nodes())
            {
                MessageBox.Show(x.ToString());
            }

How to modify the code to filter images with <section>Section 1</section> element?

Using xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication180
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement Entry = doc.Descendants().Where(x => (x.Name.LocalName == "Entry") && ((string)x.Element("findings") == "1")).FirstOrDefault();

            XNamespace ns = Entry.GetDefaultNamespace();

            List<string> images = Entry.Elements(ns + "image").Select(x => (string)x).ToList();
        }
    }
}

Please try the following solution.

c#

void Main()
{
    const string inputXMLFile = @"e:\Temp\Sanosi.xml";
    XDocument xdoc = XDocument.Load(inputXMLFile);
    
    var images = xdoc.Descendants("Entry")
        .Where(x => x.Element("section").Value.Equals("Section 1"))
        .Elements("image");
        
    Console.WriteLine(images);
}

Output

IEnumerable<XElement>

<image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
<image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>
<image>R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==</image>

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