Grouping particular nodes to their parent nodes inside XML - c#

Below given is my Sample XML:
<Response>
<Transactions>
<Upload>
<DocumentID>1</DocumentID>
<Name>A</Name>
<DocumentID>2</DocumentID>
<Name>B</Name>
</Upload>
<Upload>
<DocumentID>3</DocumentID>
<Name>C</Name>
<DocumentID>4</DocumentID>
<Name>D</Name>
</Upload>
<Upload>
<DocumentID>5</DocumentID>
<Name>E</Name>
<DocumentID>6</DocumentID>
<Name>F</Name>
</Upload>
<Transactions>
</Response>
Below given is my coming output:
<Total>
<DocumentID>1</DocumentId>
<DocumentID>2</DocumentId>
<DocumentID>3</DocumentId>
<DocumentID>4</DocumentId>
<DocumentID>5</DocumentId>
<DocumentID>6</DocumentId>
</Total>
I am using the following given code for getting my output:
var downloadfolder = #"C:\Users\KUMARMOHANTA\Desktop\New folder\test.xml";
var masterfile = new XDocument();
XElement newDocument = new XElement("Total");
masterfile.Add(newDocument);
XDocument xdoc = XDocument.Load(downloadfolder);
masterfile.Root.Add(xdoc.Descendants("DocumentId"));
masterfile.Save(#"C:\Users\KUMARMOHANTA\Desktop\merged_.xml");
But my desired output should be something like this:
<Total>
<Transactions>
<Upload>
<DocumentID>1</DocumentID>
<DocumentID>2</DocumentID>
</Upload>
<Upload>
<DocumentID>3</DocumentID>
<DocumentID>4</DocumentID>
</Upload>
<Upload>
<DocumentID>5</DocumentID>
<DocumentID>6</DocumentID>
</Upload>
<Transactions>
</Total>

Rename the element Transactions to Total. Remove elements with name Name. Then save the file.
Try this:
var downloadfolder = #"C:\Users\KUMARMOHANTA\Desktop\New folder\test.xml";
XDocument xdoc = XDocument.Load(downloadfolder);
xdoc.Root.Name = "Total";
xdoc.Descendants("Upload").Elements("Name").Remove();
xdoc.Save(#"C:\Users\KUMARMOHANTA\Desktop\merged_.xml");
Note that your XML example does not close the Transactions element.

Related

How to show specific information on xml

I have a c# console application where I update, add and delete information from an xml which works so far. But when i show the xml in my console with WriteLine it shows like this:
<ArrayOfKunde xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Kunde id="1">
<firstName>Hasan 2</firstName>
<lastName>sad</lastName>
<adress>sdfd</adress>
<birthday>vcxbgf</birthday>
<bankDetails>bcgh</bankDetails>
</Kunde>
<Kunde id="2">
<firstName>ghf</firstName>
<lastName>nbv</lastName>
<adress>bjk</adress>
<birthday>hjvn</birthday>
<bankDetails>jhgj</bankDetails>
</Kunde>
<Kunde id="3">
<firstName>mbn,</firstName>
<lastName>hgj</lastName>
<adress>ghj</adress>
<birthday>ghjg</birthday>
<bankDetails>hghj</bankDetails>
</Kunde>
</ArrayOfKunde>
it is probably due to my code to print it:
string filepath = "customerdatabase2.xml";
var xDoc = XDocument.Load(filepath);
Console.WriteLine(xDoc);
I wanted to ask if there is any way for me to filter what is shown? For example I do not want to show:
<ArrayOfKunde xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Use: XDocument.Descendants
So your code can be:
string filepath = "customerdatabase2.xml";
var xDoc = XDocument.Load(filepath);
foreach (var node in xDoc.Descendants().Skip(1))
Console.WriteLine(node);
But this is very much tied to your Xml structure. Note that I am skipping 1st descendant because that will be the Top level ArrayOfKunde node.

Change XML element value in c#

My C# code:
XDocument doc = XDocument.Load(filename);
IEnumerable<XElement> collection =
doc.Elements("BCIRequest").Elements("Card").Elements("SelectedPIN");
My XML document:
<?xml version="1.0" encoding="utf-8"?>
<BCIRequest Version="2.0"
xmlns="urn:xxxxxx:bci:request">
<Header>
<SenderCode>XX99</SenderCode>
<SenderID>9999</SenderID>
<SequenceNumber>123</SequenceNumber>
<CardGroupCount>2</CardGroupCount>
<CardCount>4</CardCount>
<BlockCount>2</BlockCount>
</Header>
<!--card groups (must precede cards and blocks)-->
<CardGroup RequestID="1">
<CustomerNumber>XX01234567</CustomerNumber>
<CardGroupName Emboss="true">GROUP ONE</CardGroupName>
</CardGroup>
<CardGroup RequestID="2"
RequestRef="87416CB7-DAEF-483A-BD08-1A885531D958">
<CustomerNumber>XX12345678</CustomerNumber>
<CardGroupName Emboss="false">GROUP TWO</CardGroupName>
</CardGroup>
<Card RequestID="3">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">MARGE SIMPSON</Driver>
</DriverCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<GeneratedPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="4">
<CustomerNumber>XX12345678</CustomerNumber>
<VehicleCard>
<VRN Emboss="true">KYI 830</VRN>
</VehicleCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="5">
<CustomerNumber>XX01234567</CustomerNumber>
<BearerCard>
<Bearer Emboss="true">OPEN XXXXXX</Bearer>
</BearerCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<FleetPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Block RequestID="6">
<CustomerNumber>XX01234567</CustomerNumber>
<PAN>7002999999999999991</PAN>
</Block>
<Card RequestID="7"
RequestRef="956EA6C5-7D7E-4622-94D0-38CAD9FCC8DF">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">HOMER SIMPSON</Driver>
<VRN Emboss="true">795 DVI</VRN>
</DriverCard>
<EmbossText>SPRINGFIELD POWER</EmbossText>
<CardTypeID>10</CardTypeID>
<TokenTypeID>20</TokenTypeID>
<PurchaseCategoryID>30</PurchaseCategoryID>
<ExpiryDate>2018-12</ExpiryDate>
<Reissue>true</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>true</OdoPrompt>
<CRNPrompt>true</CRNPrompt>
<!--address with optional fields specified-->
<CardDeliveryAddress OneTimeUse="false">
<ContactName>M xxxx</ContactName>
<ContactTitle>Mr</ContactTitle>
<CompanyName>Sxxxx</CompanyName>
<Line1>Sector 22-F</Line1>
<Line2>Springfield Power Plant</Line2>
<Line3>xxx Road</Line3>
<City>xxxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxx</CountryCode>
</CardDeliveryAddress>
<!--address with only required fields-->
<PINDeliveryAddress OneTimeUse="true">
<Line1>xxxx</Line1>
<City>xxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxxx</CountryCode>
</PINDeliveryAddress>
<Limits>
<Value Transaction="unlimited" Daily="200" Weekly="unlimited" Monthly="400"/>
<Volume Transaction="100" Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Transactions Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Day Monday="true" Tuesday="true" Wednesday="true" Thursday="true" Friday="true" Saturday="false" Sunday="false"/>
<Time Start="unlimited" End="17:00:00"/>
</Limits>
<Products>
<FuelProductRestrictionID>40</FuelProductRestrictionID>
<NonFuelProductRestrictionID>51</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>52</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>53</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>54</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>55</NonFuelProductRestrictionID>
</Products>
</Card>
<Block RequestID="8"
RequestRef="69A3E44D-DC10-4BEE-9249-1FC3C651BA0E">
<CustomerNumber>xxxxx</CustomerNumber>
<PAN>xxxxxx</PAN>
</Block>
</BCIRequest>
I need to update the element value in the above values. The old value is:
<SelectedPIN>0123</SelectedPIN>
And the new value should be:
<SelectedPIN EncryptedPIN="TKDS" FormNumber="000793906306">****</SelectedPIN>
Can anyone can help me on this?
If I selected the BCIRequest element, it's returning a null value. I've tried many solutions but unable to get one working on this XML file.
There many ways an Xml can be be modified, I prefer XDocument
XDocument doc = XDocument.Parse(input);
foreach (var element in doc.Descendants("SelectedPIN")) // filter if you want single element, in example I modifed for all elements.
{
element.Add(new XAttribute("EncryptedPIN", "TKDS"));
element.Add(new XAttribute("FormNumber", "000793906306"));
element.Value = "xxxxx"; //new value
}
and finally you can save the document using
doc.Save();
Take a look at this Demo
The root node (BCIRequest) contains a namespace so you need to include that into your query. Something like this should work:
XNamespace ns = "urn:xxxxxx:bci:request";
IEnumerable<XElement> collection = doc.Elements(ns + "BCIRequest").Elements(ns + "Card").Elements(ns + "SelectedPIN");

c#: Add element to second nesting in xml

I have a XML which looks like:
<users>
<user id="0">
<name>John</name>
<lastName>Smith</lastName>
<bills>
<bill id="0">
<name>Water</name>
<forMonth>2013-12-01</forMonth>
<money>235</money>
<lastDayToPay>2014-01-02</lastDayToPay>
<payed>False</payed>
</bill>
<bill id="1">
<name>Telephone</name>
<forMonth>2013-11-01</forMonth>
<money>690</money>
<lastDayToPay>2014-01-01</lastDayToPay>
<payed>True</payed>
</bill>
</bills>
</user>
How can i add new bill for the user, i have problem accessing "bills" node and adding element to it. I'm using c#.
use following code
XmlDocument myDocument = new XmlDocument();
myDocument.Load(XMLFile);
XmlNode newNode = myDocument.CreateElement("bill");
//add values;
var requiredNode = myDocument.ChildNodes.OfType<XmlElement>().Where(o => o.Name == "bills").First();
requiredNode.AppendChild(newNode);
myDocument.Save(XMLFile);

Trying to parse xml in Windows Phone 7.8 app but getting null value?

I am trying to parse a xml that I got as response to webservice response the xml is shown below
<GeneralSearchResponse>
<serverDetail></serverDetail>
<exceptions exceptionCount="1"></exceptions>
<clientTracking height="19" type="logo" width="106"></clientTracking>
<searchHistory></searchHistory>
<categories matchedCategoryCount="1" returnedCategoryCount="1">
<category id="0">
<name>bart</name>
<categoryURL>http://www.shopping.com/bart/products?oq=bart&linkin_id=7000610
</categoryURL>
<items matchedItemCount="1045" pageNumber="1" returnedItemCount="5">
<product id="130506037"></product>
<product id="104483377"></product>
<offer featured="false" id="tp-VCdOoO1RL6xICeRONqg==" smartBuy="false" used="false"></offer>
<offer featured="false" id="12evWWi57lddzFufngUWsg==" smartBuy="false" used="false"></offer>
<product id="96754577"></product>
</items>
<attributes matchedAttributeCount="5" returnedAttributeCount="5"></attributes>
<contentType>hybrid</contentType>
</category>
<intActualCategoryCount>4</intActualCategoryCount>
</categories>
<relatedTerms></relatedTerms>
</GeneralSearchResponse>
But when I am trying to parse using following code I am not able to get any descend or any node
XDocument xDoc = new XDocument();
xDoc = XDocument.Parse(data);
var xEle = xDoc.Root.Descendants("categories");
But xEle is not having any categories. Please let me know what is the issue??
Your XML has a default namespace - so the elements in it are in that namespace. The methods which find elements in LINQ to XML are namespace sensitive. You want:
XNamespace ns = "urn:types.partner.api.shopping.com";
XDocument xDoc = new XDocument();
xDoc = XDocument.Parse(data);
var xEle = xDoc.Root.Descendants(ns + "categories");

XML string to XML document

I have a whole XML document in a String which i need to convert to a XML document and parse tags in the document
This code sample is taken from csharp-examples.net, written by Jan Slama:
To find nodes in an XML file you can use XPath expressions. Method XmlNode.Selec­tNodes returns a list of nodes selected by the XPath string. Method XmlNode.Selec­tSingleNode finds the first node that matches the XPath string.
XML:
<Names>
<Name>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Name>
<Name>
<FirstName>James</FirstName>
<LastName>White</LastName>
</Name>
</Names>
CODE:
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/Names/Name");
foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
Using Linq to xml
Add a reference to System.Xml.Linq
and use
XDocument.Parse(string xmlString)
Edit: Sample follows, xml data (TestConfig.xml)..
<?xml version="1.0"?>
<Tests>
<Test TestId="0001" TestType="CMD">
<Name>Convert number to string</Name>
<CommandLine>Examp1.EXE</CommandLine>
<Input>1</Input>
<Output>One</Output>
</Test>
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
<Test TestId="0005" TestType="GUI">
<Name>Count characters</Name>
<CommandLine>FinalExamp.EXE</CommandLine>
<Input>This is a test</Input>
<Output>14</Output>
</Test>
<Test TestId="0006" TestType="GUI">
<Name>Another Test</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>Test Input</Input>
<Output>10</Output>
</Test>
</Tests>
C# usage...
XElement root = XElement.Load("TestConfig.xml");
IEnumerable<XElement> tests =
from el in root.Elements("Test")
where (string)el.Element("CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));
This code produces the following output:
0002
0006
Depending on what document type you want you can use XmlDocument.LoadXml or XDocument.Load.
Try this code:
var myXmlDocument = new XmlDocument();
myXmlDocument.LoadXml(theString);

Categories