Remove children nodes in XML using Linq - c#

I have an XML file with a list of parent nodes and childe nodes nested within the parent node, and I need to remove the child nodes when a specific criteria is been met.
Ex: Remove all contact nodes where the id = 1. How can I achieve this using linq and xml. This is my XML structure
<Events>
<Event>
<id>1</id>
<title>AA</title>
<start>2019-12-01T14:13:58.863</start>
<end>2019-12-01T15:13:58.787</end>
<contacts>
<contact>
<id>1</id>
<name>ABC</name>
</contact>
<contact>
<id>2</id>
<name>ABCD</name>
</contact>
<contact>
<id>3</id>
<name>ABCDE</name>
</contact>
</contacts>
</Event>
<Event>
<id>2</id>
<title>BB</title>
<start>2019-12-01T14:13:58.863</start>
<end>2019-12-01T15:13:58.787</end>
<contacts>
<contact>
<id>1</id>
<name>ABC</name>
</contact>
<contact>
<id>2</id>
<name>ABCD</name>
</contact>
<contact>
<id>3</id>
<name>ABCDE</name>
</contact>
</contacts>
</Event>
</Events>

You can get the XML nodes using this query
var query = xmlDoc.Descendants("contact").Where(e => e.Element("id").Value.Equals(id)).ToList();
And then run
query.Remove()
to remove the elements that were returned.

As Jon Skeet pointed out there is no need to do anything esoteric. Here is a complete example how to do it. Pure LINQ to XML.
c#, LINQ to XML
void Main()
{
const string inputXML = #"e:\Temp\MikeOconner.xml";
const string outputXML = #"e:\Temp\MikeOconner_output.xml";
XDocument xml = XDocument.Load(inputXML);
xml.Root.DescendantsAndSelf("contact")
.Where(r => (string)r.Element("id").Value == "1")
.Remove();
xml.Save(outputXML);
}

Related

Unable to parse xml string using Xdocument and Linq

I would like to parse the below xml using XDocument in Linq.
<?xml version="1.0" encoding="UTF-8"?>
<string xmlns="http://tempuri.org/">
<Sources>
<Item>
<Id>1</Id>
<Name>John</Name>
</Item>
<Item>
<Id>2</Id>
<Name>Max</Name>
</Item>
<Item>
<Id>3</Id>
<Name>Ricky</Name>
</Item>
</Sources>
</string>
My parsing code is :
var xDoc = XDocument.Parse(xmlString);
var xElements = xDoc.Element("Sources")?.Elements("Item");
if (xElements != null)
foreach (var source in xElements)
{
Console.Write(source);
}
xElements is always null. I tried using namespace as well, it did not work. How can I resolve this issue?
Try below code:
string stringXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><string xmlns=\"http://tempuri.org/\"><Sources><Item><Id>1</Id><Name>John</Name></Item><Item><Id>2</Id><Name>Max</Name></Item><Item><Id>3</Id><Name>Ricky</Name></Item></Sources></string>";
XDocument xDoc = XDocument.Parse(stringXml);
var items = xDoc.Descendants("{http://tempuri.org/}Sources")?.Descendants("{http://tempuri.org/}Item").ToList();
I tested it and it correctly shows that items has 3 lements :) Maybe you used namespaces differently (it's enough to inspect xDoc objct in object browser and see its namespace).
You need to concatenate the namespace and can directly use Descendants method to fetch all Item nodes like:
XNamespace ns ="http://tempuri.org/";
var xDoc = XDocument.Parse(xmlString);
var xElements = xDoc.Descendants(ns + "Item");
foreach (var source in xElements)
{
Console.Write(source);
}
This prints on Console:
<Item xmlns="http://tempuri.org/">
<Id>1</Id>
<Name>John</Name>
</Item><Item xmlns="http://tempuri.org/">
<Id>2</Id>
<Name>Max</Name>
</Item><Item xmlns="http://tempuri.org/">
<Id>3</Id>
<Name>Ricky</Name>
</Item>
See the working DEMO Fiddle

XDocument.XPathSelectElements doesn't work as expected

Sometimes C# driving me crazy, guys :) !
I tried a very simple code:
String pathToXMLFile = openFileDialog2.FileName;
var xdoc = XDocument.Load(pathToXMLFile);
var xElements = xdoc.XPathSelectElements("//NotificationData");
foreach (XElement xe in xElements)
{
Console.WriteLine(xe);
xe.RemoveAll();
}
xdoc.Save("c:/Temp/ReestrZalogovRuManyCollateralItemsSimple_output.xml");
and a very simple XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PledgeNotificationToNotary xmlns="http://fciit.ru/eis2/ruzdi/types/2.2" version="2.2">
<NotificationId>7d8b62c2-7682-43f8-8a2c-ef4296296210</NotificationId>
<NotificationNotaryAddress/>
<NotificationData version="2.2">
<FormUZ1>
<PersonalProperties>
<PersonalProperty>
<OtherProperty>
<Description>Движимое имущество, согласно перечню по договору купли-продажи </Description>
</OtherProperty>
</PersonalProperty>
</PersonalProperties>
<Pledgors>
<Pledgor>
<Organization>
<RussianOrganization>
<NameFull>dgdgdfgdf</NameFull>
<OGRN>35345345</OGRN>
<INN>34534545</INN>
<Address>
<RegionCode>77</RegionCode>
<Region>Москва</Region>
<Street>Малая Семеновская</Street>
<House>fggdgdf</House>
<Building>dfgdfg</Building>
<Apartment>54654646dfg</Apartment>
</Address>
</RussianOrganization>
</Organization>
</Pledgor>
</Pledgors>
<Pledgee>
<Pledgee>
<Organization>
<RussianOrganization>
<NameFull>Тимер Банк (публичное акционерное общество)</NameFull>
<OGRN>1021600000146</OGRN>
<INN>1653016689</INN>
<Address>
<RegionCode>16</RegionCode>
<Region>Республика Татарстан (Татарстан)</Region>
<City>Казань</City>
<Street>проспект Ибрагимова</Street>
<House>58</House>
</Address>
<Email>dfgdgdgdg#timerbank.ru</Email>
</RussianOrganization>
</Organization>
</Pledgee>
</Pledgee>
<PledgeContract>
<Name>ДОГОВОР О ЗАЛОГЕ</Name>
<Date>2018-08-20</Date>
<Number>№ДОКЛЮ/7777/77-7</Number>
<TermOfContract>«01» июня 2028 года</TermOfContract>
</PledgeContract>
<NotificationApplicant>
<Role>2</Role>
<Organization>
<NameFull>Тимер Банк (публичное акционерное общество)</NameFull>
<URN>1021600000146</URN>
<UINN>1653016689</UINN>
<Email>fgdfggsdfgsdfg#timerbank.ru</Email>
</Organization>
<Attorney>
<Name>
<Last>dfgfg</Last>
<First>dfgsdfg</First>
<Middle>sdfgdfg</Middle>
</Name>
<BirthDate>1967-08-01</BirthDate>
<Authority>приказ dgdfgdfgfdg</Authority>
<PersonDocument>
<Code>33</Code>
<Name>Паспорт гражданина Российской Федерации</Name>
<SeriesNumber>2323 232323</SeriesNumber>
</PersonDocument>
<PersonAddress>
<AddressRF registration="true">
<RegionCode>16</RegionCode>
<Region>Республика Татарстан (Татарстан)</Region>
<City>Казань</City>
<Street>gfdgdfg</Street>
<House>343434</House>
</AddressRF>
</PersonAddress>
</Attorney>
</NotificationApplicant>
</FormUZ1>
</NotificationData>
</PledgeNotificationToNotary>
The problem is xdoc.XPathSelectElements in this code doesn't return any Elements.
I thought, may be I haven't yet woken up and tried to test my XML and XPath in the first site in Google for XPath online evulation - https://www.freeformatter.com/xpath-tester.html and my XPath //NotificationData works with this XML like a charm.
But why it doesn't work in C#? :)
Thank you in advance!

How Parse Xml Without serialization and store each node Xpath

I have following xml file. I want to parse it without Serilization in C#.
<StudentList>
<StudentCount>5</StudentCount>
<Student>
<Id>1</Id>
<Name>Abc</Name>
</Student>
<Student>
<Id>2</Id>
<Name>Efg</Name>
</Student>
<Student>
<Id>3</Id>
<Name>Ghi</Name>
</Student>
<Student>
<Id>4</Id>
<Name>Jkl</Name>
</Student>
<Student>
<Id>5</Id>
<Name>Mno</Name>
</Student>
</StudentList>
I want to store above xml data in List of Student class
List<Student>
Class Student
{
public int Id = 0;
public string Name = "";
}
Here i also want a Xpath of each value node
For Ex :
StudentList\StudentCount
StudentList\Student\Id
StudentList\Student\Name
Please help me
How do i achieve this???
Quick solution to get you started:
Create an XElement:
XElement studentXml = XElement.Parse (
#"<StudentList>
<StudentCount>5</StudentCount>
<Student>
<Id>1</Id>
<Name>Abc</Name>
</Student>
<Student>
<Id>2</Id>
<Name>Efg</Name>
</Student>
<Student>
<Id>3</Id>
<Name>Ghi</Name>
</Student>
<Student>
<Id>4</Id>
<Name>Jkl</Name>
</Student>
<Student>
<Id>5</Id>
<Name>Mno</Name>
</Student>
</StudentList>");
..And select from it:
var students =
studentXml
.Descendants()
.Where(node => node.Name == "Student")
.Select(node =>
new Student {
Id = int.Parse(node.Descendants()
.First(item => item.Name == "Id")
.Value),
Name = node.Descendants()
.First(item => item.Name == "Name")
.Value
});
Try to parse the .xml using LINQ (check LINQ to read XML for an example on how to do this). You should be able to implement your other requirements from there - try it yourself and ask for help if you get stuck while coding :)

linq to xml navigate through xml c#

I have some XML and need to be able to read the data within.
A sample of the XML is
<?xml version="1.0" ?>
<ConsumeLeadRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LeadType>Mortgage</LeadType>
<LeadXml>
<ns1:LeadAssigned xmlns:ns1="http://YaddaYadda" xmlns:ns0="http://YaddaYadda" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns0:Lead>
<Reference>1234</Reference>
<Product>
<Mnemonic>Mortgage</Mnemonic>
<Description>Mortgage Leads</Description>
<SubType>Other</SubType>
</Product>
<ExtendedInfo>
<Mortgage>
<MortgageValue>75000</MortgageValue>
<MortgageValueLowerBound>1</MortgageValueLowerBound>
<MortgageValueUpperBound>500</MortgageValueUpperBound>
<PropertyValue>100000</PropertyValue>
<PropertyValueLowerBound>1</PropertyValueLowerBound>
<PropertyValueUpperBound>500</PropertyValueUpperBound>
<Adverse>false</Adverse>
<FirstTime>false</FirstTime>
</Mortgage>
</ExtendedInfo>
<Applicants>
<Applicant1>
<Title>Mr</Title>
<Forename>SampleForename</Forename>
<Surname>SampleSurname</Surname>
<DateOfBirth>1903-02-01</DateOfBirth>
<Smoker>false</Smoker>
<TelephoneNumbers>
<TelephoneNumber>
<Number>01244123456</Number>
<Type>Mobile</Type>
</TelephoneNumber>
</TelephoneNumbers>
<EmailAddresses>
<EmailAddress>
<Email>test#moneysupermarket.com</Email>
<Type>Business</Type>
</EmailAddress>
</EmailAddresses>
<Addresses>
<Address>
<Street>Sample Street</Street>
<District>Sample District</District>
<Town>Sample Town</Town>
<County>Sample County</County>
<Postcode>CH53UZ</Postcode>
<Type>Home</Type>
</Address>
</Addresses>
</Applicant1>
</Applicants>
</ns0:Lead>
<Assignment>
<Price>20</Price>
<AssignmentDateTime>2010-02-01T00:00:00</AssignmentDateTime>
<Subscription>
<Reference>1234</Reference>
<Subscriber>
<Title>Mr</Title>
<Forename>SampleForename</Forename>
<Surname>SampleSurname</Surname>
</Subscriber>
</Subscription>
<Account>
<Reference>1234</Reference>
<CompanyName>Sample Company</CompanyName>
</Account>
<LeadType>SampleLeadType</LeadType>
<TerritoryName>UNITED KINGDOM</TerritoryName>
</Assignment>
</ns1:LeadAssigned>
</LeadXml>
<AuthenticationUsername>Username</AuthenticationUsername>
<AuthenticationPassword>Password</AuthenticationPassword>
</ConsumeLeadRequest>
Using Linq to XML how do i navigate to the items?
Thanks
Sp
I have tried a few things like
XDocument Leads = XDocument.Load(#"C:\Users\Steven.Pentleton\AppData\Local\Temporary Projects\PAALeadImport\PAAExmple.xml");
var Lead = (from L in Leads.Descendants("Lead")
select new { LeadType = (string)L.Element("Reference") }).ToList();
var S = Lead.First();
string T = S.LeadType;
Are you looking for XDcoument or XElement in linq
Namespace: using System.Xml.Linq;
I guess you are looking for a Linq To Xml guide

Need a Nested LINQ to XML query help

i have a XML file as follows:
<?xml version="1.0" encoding="utf-8" ?>
<publisher>
<name>abc</name>
<link>http://</link>
<description>xyz</description>
<category title="Top">
<item>
<title>abc</title>
<link>http://</link>
<pubDate>1</pubDate>
<description>abc</description>
</item>
<item>
<title>abc</title>
<link>http://</link>
<pubDate>2</pubDate>
<description>abc</description>
</item>
</category>
<category title="Top2">
<item>
<title>abc</title>
<link>http://</link>
<pubDate>1</pubDate>
<description>abc</description>
</item>
<item>
<title>abc</title>
<link>http://</link>
<pubDate>2</pubDate>
<description>abc</description>
</item>
</category>
</publisher>
I need to write a LINQ to XML query in C# which returns everything under a "category" tag based on the value of attribute provided. I have tried the following code but it gives me error. Any help will be appreciated:
System.Xml.Linq.XElement xml = System.Xml.Linq.XElement.Parse(e.Result);
IEnumerable<string> items = from category in xml.Elements("category")
where category.Attribute("title").Value == "Top"
select category.ToString();
IEnumerable<string> items = from category in xml.Descendants("category")
where category.Attribute("title").Value == "Top"
select category.ToString();
Of course, that's going to give you a list with one string in it. If you want just the string in it:
var items = (from category in xml.Descendants("category")
where category.Attribute("title").Value == "Top"
select category.ToString()).First();
But, if you want to continue processing the XML, you probably really want it as a XElement object:
var items = (from category in xml.Descendants("category")
where category.Attribute("title").Value == "Top"
select category).First();

Categories

Resources