How to add XNamespace to XDocument's root element? - c#

I'm generating Xml Documemnt via Linq To Xml. It is added 'xmlns' attribute to all elements with empty values.
How to remove unwanted attributes?
XNamespace np = "example";
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", string.Empty),
new XElement(np + "root")
);
var list = new List<string> { "1", "2", "3" };
foreach (var item in list)
{
var xE = new XElement("child",
new XElement("first", item),
new XElement("second", item)
);
doc.Root.AddFirst(xE);
}
I expect the result.
Only xmlns attribute in root element
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="example">
<child>
<first>3</first>
<second>3</second>
</child>
<child >
<first>2</first>
<second>2</second>
</child>
<child>
<first>1</first>
<second>1</second>
</child>
</root>
But getting
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="example">
<child xmlns=""> //unwanted attribute
<first>3</first>
<second>3</second>
</child>
<child xmlns="">
<first>2</first>
<second>2</second>
</child>
<child xmlns="">
<first>1</first>
<second>1</second>
</child>
</root

It needs to add XNamespace to every XElement.
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", string.Empty),
new XElement(np + "root")
);
var list = new List<string> { "1", "2", "3" };
foreach (var item in list)
{
var xE = new XElement(np+"child",
new XElement(np+"first", item),
new XElement(np+"second", item)
);
doc.Root.AddFirst(xE);
}

Related

Can not create XML in one method and then append child nodes in another method

I have following code I want to use:
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
WriteXmlFile("PartNew", doc);
}
public static void WriteXmlFile(string nextItem, XmlDocument doc)
{
XmlElement root = doc.DocumentElement;
XmlElement id = doc.CreateElement(nextItem);
id.SetAttribute("Part", nextItem);
doc.DocumentElement.AppendChild(id);
root.AppendChild(id);
}
The problem is that I am getting an error message saying that my DocumentElement is null. This is the line where I get the error message doc.DocumentElement.AppendChild(id);. I googled but I didn't find any similar case I have. What do I miss to get my code running?
Error message:
NullReferenceException on object DocumentElement
You do not create a root element.
XmlDocument doc = new XmlDocument();
XmlNode rootNode = doc.CreateElement("root");
doc.AppendChild(rootNode);
Instead of using XmlDocument and all those manipulations with adding XML declarations, you could use LINQ-aware XDocument:
var xml = new XDocument(
new XDeclaration("1.0","utf-8", "yes"),
new XElement("root",
new XElement("PartNew", new XAttribute("Part", "1"))));
Console.WriteLine(xml.Declaration.ToString() + "\n" + xml.ToString());
Output:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<PartNew Part="1" />
</root>
You can apply LINQ to create elements:
var xml2 = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("root",
from x in new[] {1, 2, 3}
select new XElement("PartNew", new XAttribute("Part", x))));
Console.WriteLine(xml2.Declaration.ToString() + "\n" + xml2.ToString());
Output:
<root>
<PartNew Part="1" />
<PartNew Part="2" />
<PartNew Part="3" />
</root>

How to Create XML with Multiple Root Element

Following XML in my needed Output
<?xml version="1.0" encoding="UTF-8"?>
<units>
<unit>
<unit-info xmlns="">
<unit-id>4550669</unit-id>
<order-id>11949776</order-id>
<parcel-id>none</parcel-id>
<supplier-id>6</supplier-id>
</unit-info>
</unit>
</units>
for that I used following C# code:
XDocument Document = new XDocument();
XDeclaration declaration = new XDeclaration("1.0", "UTF-8", null);
Document.Declaration = declaration;
XNamespace ns = "http://www.elsevier.com/xml/ani/ani";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
XNamespace ce = "http://www.elsevier.com/xml/ani/common";
XElement nameSpaceElement = new XElement(
ns + "units", new XAttribute("xmlns", ns), new XAttribute(XNamespace.Xmlns + "xsi", xsi), new XAttribute(XNamespace.Xmlns + "ce", ce), new XAttribute(xsi + "schemaLocation",
"http://www.elsevier.com/xml/ani/ani http://www.elsevier.com/xml/ani/ani512-input-CAR.xsd"),Document.Root);
Document.Add(nameSpaceElement);
XElement uniType = new XElement("unit", new XAttribute("type", "ARTICLE"));
Document.Root.Add(uniType);
XElement unitInfo = new XElement("unit-info", new XElement("unit-id", "4550669"), new XElement("order-id", "11949776"), new XElement("parcel-id", "none"), new XElement("supplier-id", "6"), new XElement("timestamp", DateTime.Now));
Document.Root.Add(unitInfo);
Document.Save("document.txt");
But I got an output like following document
<units>
<unit></unit>
<unit-info xmlns="">
<unit-id>4550669</unit-id>
<order-id>11949776</order-id>
<parcel-id>none</parcel-id>
<supplier-id>6</supplier-id>
</unit-info>
</units>
Here my second element closed there itself. But I need to close that element as before root element.
How to get my out using XDocument and XElement.
You should add your unitInfo to uniType, not directly to the root.
something like uniType.Add(unitInfo) instead of
Document.Root.Add (unitInfo)

XML append node with main element

Hi all I have my XML as follows
<?xml version="1.0" encoding="utf-8"?>
<ApplicantDetails>
</ApplicantDetails>
I am adding dynamically the nodes based on few searches as follows
XmlDocument xDoc = new XmlDocument();
xDoc.Load(path);
XmlElement root = xDoc.DocumentElement;
XmlElement elem = null;
XmlElement e = xDoc.CreateElement("ApplicantData");
e.InnerText = string.Empty;
root.AppendChild(e);
xDoc.Save(path);
elem = xDoc.CreateElement("Mobile");
elem.InnerText = txtMobile.Text;
XmlNode node = root.SelectSingleNode("ApplicantData");
node.AppendChild(elem);
xDoc.Save(path);
Which is giving my XML as follows
<?xml version="1.0" encoding="utf-8"?>
<ApplicantDetails>
<ApplicantData>
<Mobile>1234567890</Mobile>
</ApplicantData>
</ApplicantDetails>
Now I would like to add a new node as follows
<ApplicantData>
<Mobile>1000000</Mobile>
</ApplicantData>
But with the code I have written it is appending as follows
<?xml version="1.0" encoding="utf-8"?>
<ApplicantDetails>
<ApplicantData>
<Mobile>1234567890</Mobile>
<Aadhar>
</Aadhar>
<Mobile>1234567801</Mobile>
</ApplicantData>
<ApplicantData>
</ApplicantData>
</ApplicantDetails>
Instead of XmlElement use XmlNode
XmlNode ApplicantData = xDoc.CreateElement("ApplicantData");
XmlNode elem = null;
XmlNode e = xDoc.CreateElement("ApplicantData");
e.InnerText = string.Empty;
elem = xDoc.CreateElement("Mobile");
elem.InnerText = txtMobile.Text;
ApplicantData.AppendChild(elem);
xDoc.DocumentElement.AppendChild(ApplicantData);
xDoc.Save(path);
You can use the below code to create dynamic xml.
XElement xmldata = new XElement("ApplicantDetails",
new XElement("ApplicantData", new XElement("Mobile", 1234567890)),
new XElement("ApplicantData", new XElement("Mobile", 1234567801))
);

XmlDocument.SelectSingleNode

I have a soap xml message and need to fetch a single node value from given soap xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://tews6/wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Body>
<testResult>
<Status version="6.0" >
<NNO>277982b4-2917a65f-13ffb8c0-b09751f</NNO>
</Status>
<ProfileTab>
<Email>abc#gmail.com</Email>
<Name>abc</Name>
</Profile>
</testResult></soapenv:Body></soapenv:Envelope>
I need to fetch the value of Email node. I used the below code
rootNode = "soapenv:Envelope/soapenv:Body/ProfileTab/Email";
var nsmgr = new XmlNamespaceManager(document.NameTable);
nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
node = document.SelectSingleNode(rootNode,nsmgr);
It is returning the null.
You can use the following.
var rootNode = "soapenv:Envelope/soapenv:Body/tews6:testResult/tews6:ProfileTab/tews6:Email";
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("tews6", "http://tews6/wsdl");
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
var node = doc.SelectSingleNode(rootNode, nsmgr);
Try this:
string xml="xml";
XDocument doc = XDocument.Parse(xml);
XNamespace bodyNameSpace ="http://schemas.xmlsoap.org/soap/envelope/";
var bodyXml = from _e in doc.Descendants(bodyNameSpace + "Body")
select _e;
if (bodyXml.Elements().Count() == 0)
{
return;
}
var email = from _e in bodyXml.First()Descendants("Email")
select _e;
if(email.Count()==1)
{
string emailAddress=email.First().Value;
}

Add attributes using XAttribute

I have a root XML which is like this:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data/>
<Root>
I need to add few customer related informaiton like (Name, Age etc) under Data Element Node. So, the result I expect is follows:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data>
<Name t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Elvis</Name>
<Address t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Some address</Address>
</Data>
<Root>
How can I achieve this? I am using C#, .net 4.0.
I was trying out the below code, but didn't get the result I was expecting:
string strTemplate = "<Root xmlns='http://schemas.datacontract.org/2004/07/' xmlns:t='http://www.w3.org/2001/XMLSchema-instance'><Element1>somevalue</Element1><Data/></Root>";
XDocument doc = XDocument.Parse(strTemplate);
XElement rootElement = doc.Root;
XElement dataElement = null;
foreach (XElement descendant in rootElement.Descendants())
{
if (descendant.Name.LocalName == "Data")
{
dataElement = descendant;
break;
}
}
string cusData = "<CustData><Name>Elvis</Name><Address>XYZ</Address></CustData>";
XElement customerElements = XElement.Parse(cusData);
if (dataElement != null)
{
foreach (XElement custAttributes in customerElements.Descendants())
{
XNamespace t = "http://www.w3.org/2001/XMLSchema-instance";
var attribute = new XAttribute(t + "type", "xs:string");
var attribute1 = new XAttribute(XNamespace.Xmlns + "s", "http://www.w3.org/2001/XMLSchema");
XElement element = new XElement(custAttributes.Name, attribute, attribute1);
element.Value = custAttributes.Value;
dataElement.Add(element);
}
}
string strPayload = doc.ToString();
When I execute the code I get the following:
<Data xmlns="http://schemas.datacontract.org/2004/07/">
<Name t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">Elvis</Name>
<Address t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">XYZ</Address>
</Data>
Any help appreciated!
Thanks,
M

Categories

Resources