XDocument.XPathSelectElements doesn't work as expected - c#

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!

Related

Remove children nodes in XML using Linq

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

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

XML Canonicalisation in C#

I am trying to create a canonical form of an XML input by using an XPATH expression however I am not sure if I can receiving the correct output form the document.
I am using this expression at the moment but I am expected to be able to use the second one shown however this returns no results.
I add this namespace otherwise the top does not work either
xmlnsManager.AddNamespace("x", "http://www.mytest.uk/tester");
Current XPATH -
x:testApplications/descendant-or-self::node()|//x:testApplications//#*
Expected XPATH -
/testApplicationsBatch/testApplications|/testApplicaitonsBatch/testApplications//*
In XPathVisualizer the expected path gives me the correct output however in .NET it does not.
XML DOCUMENT
<testApplicationsBatch xmlns="http://www.mytest.uk/tester" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mytest.uk/test testApplications.xsd">
<testMessageHeader>
<MessageID>00000020</MessageID>
<RegisteredBody>20130900006</RegisteredBody>
<Timestamp>2013-06-21T11:34:02</Timestamp>
<MessageCheck>8iOc6vuolwy1pFlfaSJcLZKPSruLlhYuXeTw1hCRAYi9N3MynGveElyECPyZUOBJ</MessageCheck>
</testMessageHeader>
<testApplications>
<testApplication>
<ApplicantDetails>
<Title>DR</Title>
<Forename>REJECT</Forename>
<Middlenames>
<Middlename>INTEGRITY</Middlename>
</Middlenames>
<PresentSurname>VALIDATIONTESTCASETWELVE</PresentSurname>
<CurrentAddress>
<Address>
<AddressLine1>10 LODGE COURT</AddressLine1>
<AddressTown>STAINING</AddressTown>
<AddressCounty>LANCASHIRE</AddressCounty>
<Postcode>FY3 0EJ</Postcode>
<CountryCode>GB</CountryCode>
</Address>
<ResidentFromGyearMonth>2003-07</ResidentFromGyearMonth>
</CurrentAddress>
<DateOfBirth>1977-01-01</DateOfBirth>
<Gender>male</Gender>
<NINumber>NM433816D</NINumber>
<AdditionalApplicantDetails>
<BirthTown>BLACKPOOL</BirthTown>
<BirthCounty>LANCASHIRE</BirthCounty>
<BirthCountry>GB</BirthCountry>
<BirthNationality>BRITISH</BirthNationality>
<ContactNumber>01253 897888</ContactNumber>
<UnspentConvictions>n</UnspentConvictions>
<DeclarationByApplicant>y</DeclarationByApplicant>
<LanguagePreference>english</LanguagePreference>
</AdditionalApplicantDetails>
<ApplicantIdentityDetails>
<IdentityVerified>y</IdentityVerified>
<EvidenceCheckedBy>RICHARD SMITH</EvidenceCheckedBy>
</ApplicantIdentityDetails>
</ApplicantDetails>
<PotentialEmployerDetails>
<PositionAppliedFor>HEAD TEACHER</PositionAppliedFor>
<OrganisationName>HODGSON HIGH SCHOOL</OrganisationName>
</PotentialEmployerDetails>
<RBdetails>
<RBApplicationReference>D00000128</RBApplicationReference>
<RBNumber>20130900006</RBNumber>
<CSigNumber>20130900021</CSigNumber>
<DisclosureType>standard</DisclosureType>
<WorkingWithVulnerableAdults>n</WorkingWithVulnerableAdults>
<WorkingWithChildren>n</WorkingWithChildren>
<CurrentAddressDetailsChecked>y</CurrentAddressDetailsChecked>
<Volunteer>y</Volunteer>
<WorkingAtHomeAddress>n</WorkingAtHomeAddress>
</RBdetails>
</testApplication>
</testApplications>
</testApplicationsBatch>
RETURNED CANONICAL DOCUMENT
<testApplications xmlns="http://www.mytest.uk/tester" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<testApplication>
<ApplicantDetails>
<Title>MRS</Title>
<Forename>A'BCD THISISTEST CASEONEFORENAME</Forename>
<Middlenames>
<Middlename>MIDDLENAMEOFTESTCASEONE</Middlename>
</Middlenames>
<PresentSurname>ABCDEFTHISISTESTCASEONESURNAME</PresentSurname>
<CurrentAddress>
<Address>
<AddressLine1>28 BROCKLEWOOD'S AVENUE</AddressLine1>
<AddressLine2>NEAR/HIGHCROSS-(PUB)</AddressLine2>
<AddressTown>POULTON-LE-FYLDE</AddressTown>
<AddressCounty>LANCASHIRE-TEST-COUNTY</AddressCounty>
<Postcode>FY6 7SJ</Postcode>
<CountryCode>GB</CountryCode>
</Address>
<ResidentFromGyearMonth>2013-07</ResidentFromGyearMonth>
</CurrentAddress>
<PreviousAddress>
<Address>
<AddressLine1>1(FLAT2) CUMBERLAND HOUSE</AddressLine1>
<AddressLine2>A'B-C THISISTESTCASEONEADDRESSLINETWO</AddressLine2>
<AddressTown>ABERYSTH-TOWN</AddressTown>
<AddressCounty>G</AddressCounty>
<Postcode>L2 0QN</Postcode>
<CountryCode>GB</CountryCode>
</Address>
<ResidentDates>
<ResidentFromGyearMonth>1997-01</ResidentFromGyearMonth>
<ResidentToGyearMonth>2013-07</ResidentToGyearMonth>
</ResidentDates>
</PreviousAddress>
<DateOfBirth>1977-01-13</DateOfBirth>
<Gender>female</Gender>
<NINumber>NM433816D</NINumber>
<AdditionalApplicantDetails>
<BirthSurname>A'B-CBIRTHSURNAME</BirthSurname>
<BirthSurnameUntil>2000</BirthSurnameUntil>
<OtherSurnames>
<OtherSurname>
<Name>OTHER SURNAME NAME</Name>
<UsedFrom>2000</UsedFrom>
<UsedTo>2000</UsedTo>
</OtherSurname>
</OtherSurnames>
<OtherForenames>
<OtherForename>
<Name>OTHERFORENAMENAMETESTONE</Name>
<UsedFrom>1977</UsedFrom>
<UsedTo>2000</UsedTo>
</OtherForename>
</OtherForenames>
<BirthTown>ASHTON-UNDER-LYME</BirthTown>
<BirthCounty>/1-'&COUNTYTESTONE</BirthCounty>
<BirthCountry>WS</BirthCountry>
<BirthNationality>GERMAN/-0'FRENCH</BirthNationality>
<ContactNumber>01253 897888/EXT - 1234</ContactNumber>
<UnspentConvictions>y</UnspentConvictions>
<DeclarationByApplicant>y</DeclarationByApplicant>
<LanguagePreference>english</LanguagePreference>
</AdditionalApplicantDetails>
<ApplicantIdentityDetails>
<IdentityVerified>y</IdentityVerified>
<EvidenceCheckedBy>RICHARD SMITH</EvidenceCheckedBy>
<PassportDetails>
<PassportNumber>12345678912</PassportNumber>
<PassportDob>1977-01-13</PassportDob>
<PassportNationality>BRITISH</PassportNationality>
<PassportIssueDate>2001-01-13</PassportIssueDate>
</PassportDetails>
<DriverLicenceDetails>
<DriverLicenceNumber>ABCDE 701017 AB1CS</DriverLicenceNumber>
<DriverLicenceDOB>1977-01-13</DriverLicenceDOB>
<DriverLicenceType>paper</DriverLicenceType>
<DriverLicenceValidFrom>2003-01-02</DriverLicenceValidFrom>
<DriverLicenceIssueCountry>IO</DriverLicenceIssueCountry>
</DriverLicenceDetails>
</ApplicantIdentityDetails>
</ApplicantDetails>
<PotentialEmployerDetails>
<PositionAppliedFor>CARETAKER'S ASSISTANT</PositionAppliedFor>
<OrganisationName>BIDE-A-WEE REST HOME'S/(ELDERLY&INFIRM)</OrganisationName>
</PotentialEmployerDetails>
<RBdetails>
<RBApplicationReference>ARM16</RBApplicationReference>
<RBNumber>20130800000</RBNumber>
<CSigNumber>20130800025</CSigNumber>
<DisclosureType>standard</DisclosureType>
<WorkingWithVulnerableAdults>n</WorkingWithVulnerableAdults>
<WorkingWithChildren>n</WorkingWithChildren>
<CurrentAddressDetailsChecked>y</CurrentAddressDetailsChecked>
<Volunteer>y</Volunteer>
<WorkingAtHomeAddress>n</WorkingAtHomeAddress>
</RBdetails>
</testApplication>
</testApplications>

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