How to Create XML with Multiple Root Element - c#

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)

Related

How to add XNamespace to XDocument's root element?

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

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>

Adding attribute to XML Node always fail

I always get exception below when try to add attribute, why it's not working?
The prefix '' cannot be redefined from '' to 'http://ws.plimus.com'
within the same start element tag.
Code
var docXml = new XElement("param-encryption",
new XAttribute("xmlns", "http://ws.plimus.com"),
new XElement("parameters"));
var s = docXml.ToString();
I want to get result like
<param-encryption xmlns="http://ws.plimus.com">
<parameters>
</parameters>
</param-encryption>
This simplest approach is to let LINQ to XML do this automatically by specifying the namespace in the element name:
XNamespace ns = "http://ws.plimus.com";
var docXml = new XElement(ns + "param-encryption", new XElement(ns + "parameters"));
Result of docXml.ToString():
<param-encryption xmlns="http://ws.plimus.com">
<parameters />
</param-encryption>
Try this -
XNamespace aw = "http://ws.plimus.com";
XElement root = new XElement("param-encryption",
new XAttribute(XNamespace.Xmlns + "aw", "http://ws.plimus.com"),
new XElement("Child", "child content")
);
Console.WriteLine(root);
(EDIT):-
use this if you dont want namespace alias
XNamespace aw = "http://ws.plimus.com";
XElement root = new XElement(aw + "param-encryption",
new XAttribute("xmlns", "http://ws.plimus.com"),
new XElement( aw + "Child", "child content")
);

Creating XMLDocument throguh code in asp.net

am trying to generate an XML document like this through code.
<TestRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:2292/RMSchema.xsd">
<Version>3</Version>
<ApplicationHeader>
<AppLanguage />
<UserId>rmservice</UserId>
</ApplicationHeader>
<CustomerData>
<ExistingCustomerData>
<MTN>2084127182</MTN>
</ExistingCustomerData>
</CustomerData>
</TestRequest>
I tried some samples. But they create xmlns for the children, which i dont need. Any help is really appreciated.
I have tried the below code. But it is adding only xmlns to all children, which i dont need
XmlDocument xDocument = new XmlDocument();
xDocument.AppendChild(xDocument.CreateXmlDeclaration("1.0", "windows-1252", null));
XmlElement xRoot = xDocument.CreateElement("TestRequest", "XNamespace.Xmlns=http://www.w3.org/2001/XMLSchema-instance" + " xsi:noNamespaceSchemaLocation=" + "http://localhost:2292/RMSchema.xsd");
xDocument.AppendChild(xRoot);
xRoot.AppendChild(xDocument.CreateElement("Version")).InnerText = 1;
Thanks
Tutu
I have tried with
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
XmlElement xRoot = xDocument.CreateElement("xsi","RMRequest",xsi);
xRoot.SetAttribute("noNamespaceSchemaLocation", xsi, "http://localhost:2292/RMSchema.xsd");
xDocument.AppendChild(xRoot);
Now the response is
<?xml version=\"1.0\" encoding=\"windows-1252\"?><xsi:TestRequest xsi:noNamespaceSchemaLocation=\"http://localhost:2292/RMSchema.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
Here is the awesome LINQ to XML. Enjoy!
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
XDocument doc = new XDocument(new XDeclaration("1.0", "windows-1252", null),
new XElement("TestRequest",
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(xsi + "noNamespaceSchemaLocation", "http://localhost:2292/RMSchema.xsd"),
new XElement("Version",
new XText("3")
),
new XElement("ApplicationHeader",
new XElement("AppLanguage"),
new XElement("UserId",
new XText("rmservice")
)
),
new XElement("CustomerData",
new XElement("ExistingCustomerData",
new XElement("MTN",
new XText("2084127182")
)
)
)
)
);
doc.Save(filePath);
If you really want the old API, here it is:
var xDocument = new XmlDocument();
xDocument.AppendChild(xDocument.CreateXmlDeclaration("1.0", "windows-1252", null));
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
var xRoot = xDocument.CreateElement("TestRequest");
var attr = xDocument.CreateAttribute("xsi", "noNamespaceSchemaLocation", xsi);
attr.Value = "http://localhost:2292/RMSchema.xsd";
xRoot.Attributes.Append(attr);
xRoot.AppendChild(xDocument.CreateElement("Version")).InnerText = "1";
// .. your other elemets ...
xDocument.AppendChild(xRoot);
xDocument.Save(filePath);
EDIT: From your comments, it looks like you want the xmlns:xsi and other attribute in that specific order. If so, you may have to trick the XmlDocument to add the xmlns:xsi attribute first.
var xDocument = new XmlDocument();
xDocument.AppendChild(xDocument.CreateXmlDeclaration("1.0", "windows-1252", null));
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
var xRoot = xDocument.CreateElement("TestRequest");
// add namespace decl are attribute
var attr = xDocument.CreateAttribute("xmlns:xsi");
attr.Value = xsi;
xRoot.Attributes.Append(attr);
// no need to specify prefix, XmlDocument will figure it now
attr = xDocument.CreateAttribute("noNamespaceSchemaLocation", xsi);
attr.Value = "http://localhost:2292/RMSchema.xsd";
xRoot.Attributes.Append(attr);
xRoot.AppendChild(xDocument.CreateElement("Version")).InnerText = "1";
// .. your other elemets ...
xDocument.AppendChild(xRoot);
xDocument.Save(filePath);
Are you looking for something like this:-
XmlDocument xmldoc = new XmlDocument();
XmlNode root = xmldoc.AppendChild(xmldoc.CreateElement("Root"));
XmlNode child = root.AppendChild(xmldoc.CreateElement("Child"));
XmlAttribute childAtt =child.Attributes.Append(xmldoc.CreateAttribute("Attribute"));
childAtt.InnerText = "My innertext";
child.InnerText = "My node Innertext";
xmldoc.Save("ABC.xml");

how to display right xml format

I am trying to create an xml doc with a prefix g:
c#
static void Main(string[] args)
{
XNamespace g = "g:";
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement( g+"Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("street","this street"))
)
);
Console.WriteLine(contacts);
}
instead it shows up with:
..<contacts>
<contact>
<name xmlns="g:">
...
XNamespace g = "http://somewhere.com";
XElement contacts =
new XElement("Contacts", new XAttribute(XNamespace.Xmlns + "g", g),
new XElement("Contact",
new XElement( g+"Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("street","this street"))
)
);
OUTPUT :
<Contacts xmlns:g="http://somewhere.com">
<Contact>
<g:Name>Patrick Hines</g:Name>
<Phone>206-555-0144</Phone>
<Address>
<street>this street</street>
</Address>
</Contact>
</Contacts>
Your code is working fine for me (output is):
<Contacts>
<Contact>
<Name xmlns="g:">Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<street>this street</street>
</Address>
</Contact>
</Contacts>
if you still can not get the correct output then you can try this:
new XDocument(
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("street","this street"))
)
)
).Save("foo.xml");
XDocument is in System.Xml.Linq namespace. So, at the top of your code file, add:
using System.Xml.Linq;
Then you can write the data to your file the following way:
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
new System.Xml.Linq.XElement("Contacts"),
new XElement("Contact",
new XElement("Name", c.FirstOrDefault().DisplayName),
new XElement("PhoneNumber", c.FirstOrDefault().PhoneNumber.ToString()),
new XElement("Email", "abc#abc.com"));
doc.Save(...);

Categories

Resources