XML XElement building an xml document - c#

Hi I am new to XML building, I basically didn't use it before, I always preferred json.
I have a solution where I just make it with string and convert to XML object, but how can I do it with XElement class?
This is the document:
<?xml version="1.0" encoding="utf-8"?>
<requestblock version="3.67">
<alias>ALIAS</alias>
<request type="AUTH">
<operation>
<sitereference>test12345</sitereference>
<accounttypedescription>TEST</accounttypedescription>
<parenttransactionreference>12-3-4567</parenttransactionreference>
</operation>
<merchant>
<orderreference>Example recurring auth</orderreference>
</merchant>
<customer> </customer>
<billing>
<amount currencycode="GBP">1234</amount>
<subscription type="TEST">
<number>1</number>
</subscription>
</billing>
<settlement/>
</request>
</requestblock>
I already have a part of the code like this:
XElement address =
new XElement("alias", "TEST",
new XElement("request", new XAttribute("type", "AUTH"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
));
But I have a problem with alias, because alias is closed after all elements, not in the same notation:
<alias>TEST
<request type="AUTH">
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</request>
</alias>
As you can see notation is the problem.

You're setting alias as your root element, which should be requestblock. If you start with requestblock like this:
XElement address =
new XElement("requestblock", new XAttribute("version",3.67),
new XElement("alias", "TEST"),
new XElement("request", new XAttribute("type", "AUTH"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
It'l give you
<requestblock version="3.67">
<alias>TEST</alias>
<request type="AUTH">
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</request>
</requestblock>

Related

How to use XDocument to update existing xml file which has namespace requirements?

My XML file
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns="http://a01_data_navin"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://a01_data_navin event.xsd">
<Event>
<eventid>1</eventid>
<Photo>
<filepath>files\images\memory rep02.png</filepath>
<location>
<lat>35.496456056584158</lat>
<lon>-99.228515625</lon>
</location>
<datetimestamp>2020-03-29T00:00:00</datetimestamp>
</Photo>
</Event>
<Event>
<eventid>2</eventid>
<Photo>
<filepath>files\images\poop.jpeg</filepath>
<location>
<lat>36.137874718407268</lat>
<lon>-89.6044921875</lon>
</location>
<datetimestamp>2020-03-29T00:00:00</datetimestamp>
</Photo>
</Event>
</Root>
When i use XDocument in C#
XDocument xml = XDocument.Load(_xmlFilePath);
// create xml structure
var photo_XML = tempPhotoList.ToArray();
xml.Element("Root")?.Add(
new XElement("Event",
from photo in photo_XML
select new XElement("eventid", photo.EventId),
from photo1 in photo_XML
select new XElement("Photo",
new XElement("filepath", photo1.FileNameForPath),
new XElement("location",
new XElement("lat", photo1.GetLatitude()),
new XElement("lon", photo1.GetLongitude())),
new XElement("datetimestamp", photo1.DateTimeStamp)
))
);
When i run the above code i cant seem to enter into the xml file and iterate the tree. I would have to add a name space like this:
XDocument xml = XDocument.Load(_xmlFilePath);
// create xml structure
var photo_XML = tempPhotoList.ToArray();
xml.Element(NameSpace+"Root")?.Add(
new XElement("Event",
from photo in photo_XML
select new XElement("eventid", photo.EventId),
from photo1 in photo_XML
select new XElement("Photo",
new XElement("filepath", photo1.FileNameForPath),
new XElement("location",
new XElement("lat", photo1.GetLatitude()),
new XElement("lon", photo1.GetLongitude())),
new XElement("datetimestamp", photo1.DateTimeStamp)
))
);
With adding the Element(NameSpace+"Root"); im able to traverse through my xml file and add a new event but i end up with this..
<Event xmlns="">
<eventid>3</eventid>
<Photo>
<filepath>files\images\poop.jpeg</filepath>
<location>
<lat>17.140790393316649</lat>
<lon>1.7578125</lon>
</location>
<datetimestamp>2020-03-29T00:00:00</datetimestamp>
</Photo>
</Event>
I need some help on how to add or update a new event into an existing xml file which has namespace to deal with; using XDocument in C# ? It seems that using XDocument gets my task done.
Im stuck guys.. please help..
Try following :
XDocument xml = XDocument.Load(_xmlFilePath);
XElement root = xml.Root;
XNamespace ns = root.GetDefaultNamespace();
root.Add(new XElement(ns + "Event",
Hey everyone so this is what i did to resolve the issue in hand..
*I added namespace to every XElement instead of only at the root.. Sorry rookie mistake from before.. :P
XElement root = xml.Root;
XNamespace ns = root.GetDefaultNamespace();
root.Add(
new XElement(ns+"Event",
from photo in photo_XML
select new XElement(ns +"eventid", photo.EventId),
from photo1 in photo_XML
select new XElement(ns +"Photo",
new XElement(ns +"filepath", photo1.FileNameForPath),
new XElement(ns +"location",
new XElement(ns +"lat", photo1.GetLatitude()),
new XElement(ns +"lon", photo1.GetLongitude())),
new XElement(ns +"datetimestamp", photo1.DateTimeStamp)
))
);

Insert data from C# to XML with using Linq issue?

I am building a C# application. I want to insert the following XML data to XML.
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee ID="1">
<Name>Numeri</Name>
</Employee>
<Employee ID="2">
<Name>Ismail</Name>
</Employee>
<Employee ID="3">
<Name>jemu</Name>
</Employee>
</Employees>
Previously I have tried an XML that has not attribute value, But now I
want to insert with attribute value.
string _file = (Application.StartupPath+"/employees.xml");
XDocument doc;
if (!File.Exists(_file))
{
doc = new XDocument();
doc.Add(new XElement("Employees"));
}
else
{
doc = XDocument.Load(_file);
}
doc.Root.Add(
new XElement("Employee",
new XElement("ID", textBox1.Text),
new XElement("Name", textBox2.Text)
)
);
doc.Save(_file);
You should use XAttribute instead of XElement in order to insert ID as attribute:
doc.Root.Add(
new XElement("Employee",
new XAttribute("ID", textBox1.Text),
new XElement("Name", textBox2.Text)
)
);

How to append data to existing xml?

I have this xml file called "list.xml".
<?xml version="1.0" encoding="utf-8" ?>
<PeopleList>
<Person>
<First-Name>John</First-Name>
<Last-Name>Sims</Last-Name>
<Address-1>214,NJ Lane</Address-1>
<Address-2>Ney York</Address-2>
<Post-Code>8000</Post-Code>
<City>NJ</City>
</Person>
<Person>
<First-Name>Arya</First-Name>
<Last-Name>Stark</Last-Name>
<Address-1>214,Latin Street</Address-1>
<Address-2>Los Angeles</Address-2>
<Post-Code>302</Post-Code>
<City>CA</City>
</Person>
<Person>
<First-Name>Rick</First-Name>
<Last-Name>Rider</Last-Name>
<Address-1>500,LA Lane</Address-1>
<Address-2>Miami</Address-2>
<Post-Code>768</Post-Code>
<City>LA</City>
</Person>
</PeopleList>
How can I append following data to the above xml?
<Person>
<First-Name>Test User 1</First-Name>
<Last-Name>Test Last Name</Last-Name>
<Address-1>Test add 1</Address-1>
<Address-2>Test add 2</Address-2>
<Post-Code>Test Post code</Post-Code>
<City>Test City</City>
</Person>
Is this the correct way?
XmlDocument xd = new XmlDocument();
xd.Load("list.xml");
XmlNode nl = xd.SelectSingleNode("//Person");
XmlDocument xd2 = new XmlDocument();
xd2.LoadXml("<Person><First-Name>20</First-Name>....</Person>");
XmlNode n = xd.ImportNode(xd2.FirstChild,true);
nl.AppendChild(n);
You can use LINQ to XML
var newElement = new XElement("Person",
new XElement("First-Name", "Test User 1"),
new XElement("Last-Name", "Test Last Name"),
new XElement("Address-1", "Test add 1"),
new XElement("Address-2", "Test add 2"),
new XElement("Post-Code", "Test Post code"),
new XElement("City", "Test City")
);
var xDoc = XDocument.Load("path");
xDoc.Root.Add(newElement);
xDoc.Save(path);
See the documentation for more details: XContainer.Add Method

XML Name Space Not Formating Correctly

Building an XML XDocument to push to web service and the root element needs namespace values this is what the XML form should look like....
<shipment-feed xmlns="http://seller.marketplace.sears.com/oms/v5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://seller.marketplace.sears.com/oms/v5 asn.xsd ">
<shipment>
<header>
<asn-number>00601780002</asn-number>
<po-number>0060180</po-number>
<po-date>2009-09-26</po-date>
</header>
<detail>
<tracking-number>UPS1XXX</tracking-number>
<ship-date>2001-01-01</ship-date>
<shipping-carrier>UPS</shipping-carrier>
<shipping-method>GROUND</shipping-method>
<package-detail>
<line-number>1</line-number>
<item-id>AB12345678912345456789123456789CD</item-id>
<quantity>1</quantity>
</package-detail>
</detail>
</shipment>
</shipment-feed>
This is the xml that I'm getting....
<?xml version="1.0" encoding="utf-8"?>
<shipment-feed xmlns="http://seller.marketplace.sears.com/oms/v5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsischemalocation="http://seller.marketplace.sears.com/oms/v5 asn.xsd">
<shipment xmlns="">
<header>
<asn-number>2824565201311</asn-number>
<po-number>2824565</po-number>
<po-date>2013-11-14</po-date>
</header>
<details>
<tracking-number>579040914892</tracking-number>
<ship-date>2013-11-14</ship-date>
<shipping-carrier>FEDEX</shipping-carrier>
<shipping-method>Ground</shipping-method>
<package-details>
<line-number>1</line-number>
<item-id>LTH7XB1MW-EA</item-id>
<quantity>3</quantity>
</package-details>
</details>
</shipment>
<shipment xmlns="">
<header>
<asn-number>2821596201311</asn-number>
<po-number>2821596</po-number>
<po-date>2013-11-13</po-date>
</header>
<details>
<tracking-number>9405515901119923380663</tracking-number>
<ship-date>2013-11-14</ship-date>
<shipping-carrier>USPS</shipping-carrier>
<shipping-method>Priority Mail</shipping-method>
<package-details>
<line-number>1</line-number>
<item-id>CWD93151-EA</item-id>
<quantity>6</quantity>
</package-details>
<package-details>
<line-number>2</line-number>
<item-id>CWD93901-EA</item-id>
<quantity>4</quantity>
</package-details>
</details>
</shipment>
</shipment-feed>
This is the C# code I created....
XNamespace ns1 = "http://seller.marketplace.sears.com/oms/v5";
XNamespace ns2 = "http://www.w3.org/2001/XMLSchema-instance";
XNamespace ns3 = "http://seller.marketplace.sears.com/oms/v5 asn.xsd";
XDocument doc = new XDocument();
XElement root = new XElement(ns1 + "shipment-feed",
new XAttribute("xmlns" , "http://seller.marketplace.sears.com/oms/v5"),
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute("xsi" + "schemalocation", "http://seller.marketplace.sears.com/oms/v5 asn.xsd"));
doc.Add(root);
int x = 1;
foreach (SearsOrder s in SearsList)
{
XElement shipment = new XElement("shipment",
new XElement("header",
new XElement("asn-number", s.asnnumber),
new XElement("po-number", s.ponumber),
new XElement("po-date", s.podate)),
new XElement("details",
new XElement("tracking-number", s.trackingnum),
new XElement("ship-date", s.shipdate),
new XElement("shipping-carrier", s.carrier),
new XElement("shipping-method", s.method),
s.orderitems.Select(i => new XElement("package-details",
new XElement("line-number", x++),
new XElement("item-id", i.itemid),
new XElement("quantity", i.quantity)))
));
doc.Root.Add(shipment);
x = 1;
}
The fist problem is the first child node I'm not seeing where that is coming from because that node is not even declared until the foreach loop. I was under the impression that I was only adding attributes to the root element.
and the other problem is removing the xml declaration
This sort of the thing is the problem:
new XElement("shipment", ...)
You want the shipment elements to be in the "http://seller.marketplace.sears.com/oms/v5" namespace - so you need to make that explicit. That won't show up in the resulting XML directly, because they'll inherit that as the default namespace specified in the root. Basically, wherever you're creating an element, you probably want to use ns1. So:
new XElement(ns1 + "shipment", new XElement(ns1 + "header", ...), ...)
To understand more about why this is required, you should read up on namespace defaulting in the XML Namespaces specification.
and the other problem is removing the xml declaration
So add an XDeclaration to the XDocument:
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"))

Insert new XML node using LINQ

XML:
<Questions>
<Question>
<Id>1</Id>
<Text>aaa</Text>
<Reserver />
</Question>
<Question>
<Id>2</Id>
<Text>bbb</Text>
<Reserver />
</Question>
</Questions>
How can insert new Question using LINQ like this:
<Question>
<Id>3</Id>
<Text>ccc</Text>
<Reserver />
</Question>
XDocument doc = XDocument.Parse("<Questions>...</Questions>");
doc.Root.Add(
new XElement("Question",
new XElement("Id", 3),
new XElement("Text", "ccc"),
new XElement("Reserver"))
);
You can create a new element like this:
var newElem = new XElement("Question",
new XElement("Id", 3),
...
);
xdoc.Root.Add(newElem);

Categories