c#: Add element to second nesting in xml - c#

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

Related

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

xml error:System.Xml.XPath.XPathException: Expression must evaluate to a node-set

I am trying to find a node in my xml file but getting the error ( see title)?
// instantiate XmlDocument and load XML from file
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\temp\test2.xml");
var node = doc.SelectSingleNode("/Offers/Offer/ID=[text()='1']");
var test = node;
xml
<?xml version="1.0" encoding="utf-8"?>
<Offers>
<Offer>
<Model>AAAA</Model>
<ID>1</ID>
<Name>First offer</Name>
</Offer>
<Offer>
<Model>BBBB</Model>
<ID>2</ID>
<Name>Second offer</Name>
</Offer>
</Offers>
Remove the = after ID:
var node = doc.SelectSingleNode("/Offers/Offer/ID=[text()='1']");
becomes:
var node = doc.SelectSingleNode("/Offers/Offer/ID[text()='1']");

C# Parsing specific xml

I wonder how do I parse a specific person by the id in the xml below?
Also lets say I wanna loop through them all and add them to a listview, How do I do that with XmlDocument?
<users>
<user id="Marcus">
<website>www.google.com</website>
<type>1</type>
</user>
<user id="John">
<website>www.youtube.com</website>
<type>1</type>
</user>
<user id="Josh">
<website>www.google.com</website>
<type>2</type>
</user>
</users>
Here's a linq to xml example -
using System.Xml.Linq;
var doc = XDocument.Parse(#"...");
var element = doc.XPathSelectElement("/users/user[#id='John']");
var website = element.XPathSelectElement("website").Value;
var type = int.Parse(element.XPathSelectElement("type").Value);

how can append to xml

i have this xml.
<project>
<user>
<id>1</id>
<name>a</name>
</user>
<user>
<id>2</id>
<name>b</name>
</user>
</project>
now how can append a new element like this between element <project></project>
<user>
<id>3</id>
<name>c</name>
</user>
string xml =
#"<project>
<user>
<id>1</id>
<name>a</name>
</user>
<user>
<id>2</id>
<name>b</name>
</user>
</project>";
XElement x = XElement.Load(new StringReader(xml));
x.Add(new XElement("user", new XElement("id",3),new XElement("name","c") ));
string newXml = x.ToString();
If you mean using C# then probably the simplest way is to load the xml up into an XmlDocument object and then add a node representing the additional element.
e.g. something like:
string filePath = "original.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);
XmlElement root = xmlDoc.DocumentElement;
XmlNode nodeToAdd = doc.CreateElement(XmlNodeType.Element, "user", null);
XmlNode idNode = doc.CreateElement(XmlNodeType.Element, "id", null);
idNode.InnerText = "1";
XmlNode nameNode = doc.CreateElement(XmlNodeType.Element, "name", null);
nameNode.InnerText = "a";
nodeToAdd.AppendChild(idNode);
nodeToAdd.AppendChild(nameNode);
root.AppendChild(nodeToAdd);
xmlDoc.Save(filePath); // Overwrite or replace with new file name
But you haven't said where the xml fragments are - in files/strings?
If you have the below XML file:
<CATALOG>
<CD>
<TITLE> ... </TITLE>
<ARTIST> ... </ARTIST>
<YEAR> ... </YEAR>
</CD>
</CATALOG>
and you have to add another <CD> node with all its child nodes:
using System.Xml; //use the xml library in C#
XmlDocument document = new XmlDocument(); //creating XML document
document.Load(#"pathOfXmlFile"); //load the xml file contents into the newly created document
XmlNode root = document.DocumentElement; //points to the root element (catalog)
XmlElement cd = document.CreateElement("CD"); // create a new node (CD)
XmlElement title = document.CreateElement("TITLE");
title.InnerXML = " ... "; //fill-in the title value
cd.AppendChild(title); // append title to cd
XmlElement artist = document.CreateElement("ARTIST");
artist.InnerXML = " ... ";
cd.AppendChild(artist);
XmlElement year = document.CreateElement("YEAR");
year.InnerXML = " ... ";
cd.AppendChild(year);
root.AppendChild(cd); // append cd to the root (catalog)
document.save(#"savePath");//save the document

insert node in xml file

i have a xml file that looks like the following, and i need to edit it in c# to insert a new node:
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<Name>John Smith</Name>
<test>
<Date>23.05.2011</Date>
<points>33</points>
</test>
<test>
<Date>22.06.2011</Date>
<points>29</points>
</test>
</User>
<User>
<Name>David Chris</Name>
<test>
<Date>01.02.2009</Date>
<points>25</points>
</test>
<test>
<Date>14.01.2010</Date>
<points>231</points>
</test>
</User>
i need to insert another "in this example a third" Element to the user called "John Smith" with all the sub elements..
so the xml will become :
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<Name>John Smith</Name>
<test>
<Date>23.05.2011</Date>
<points>33</points>
</test>
<test>
<Date>22.06.2011</Date>
<points>29</points>
</test>
<test>
<Date>30.10.2011</Date>
<points>21</points>
</test></b>
</User>
<User>
<Name>David Chris</Name>
<test>
<Date>01.02.2009</Date>
<points>25</points>
</test>
<test>
<Date>14.01.2010</Date>
<points>231</points>
</test>
</User>
any help is really appreciated ..
thanks a lot ..
Simple (assuming you're using .NET 3.5 or higher):
Load the document (e.g. using XDocument.Load)
Add the relevant element (create a new XElement, find the insertion point, call insertionPoint.Add(newElement))
Save the document (XDocument.Save)
LINQ to XML makes almost all XML-based tasks simpler than older APIs... if the above isn't a good enough start, I'd strongly recommend reading a tutorial on LINQ to XML.
There's no simple way of inserting the new element without reading the old file totally, manipulating it and then writing it out totally. In theory you could do it in a streaming fashion with XmlReader and XmlWriter, but they're almost always more trouble than they're worth.
class Program
{
static void Main()
{
var doc = XDocument.Load("test.xml");
var johnSmith = doc
.Descendants("User")
.Descendants("Name")
.Where(x => x.Value == "John Smith")
.Select(x => x.Parent)
.First();
johnSmith.Add(
new XElement("test",
new XElement("Date", "30.10.2011"),
new XElement("points", "21")
)
);
doc.Save("new.xml");
}
}
For .NET Framework 3.5 and higher: XDocument
For .NET Framework 1.1 and higher: XmlDocument
Here you go:
class Program
{
static void Main(string[] args)
{
XElement main = XElement.Load(#"users.xml");
// write new data to new file
string newDate = "01.01.2012";
string newPoints = "42";
main.Descendants("User")
.Descendants("Name")
.Where(e => e.Value == "John Smith")
.Select(e => e.Parent)
.First()
.Add(new XElement("test",
new XElement("date", newDate),
new XElement("points", newPoints)
)
);
main.Save("users2.xml");
}
}

Categories