How to create an Xml with multiple namescapes using XDocument - c#

I would like to create a document with multiple namespaces (see Xml below). How can I do that using XDocument? My final result should the following:
<?xml version="1.0" encoding="utf-8"?>
<a:feed xmlns:a="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://schemas.zune.net/catalog/apps/2008/02">
<a:link rel="prev" type="application/atom+xml" href="myUrl" />
<a:link rel="next" type="application/atom+xml" href="myUrl" />
<a:link rel="self" type="application/atom+xml" href="myUrl" />
<a:updated>2008-05-20T22:50:46.7932864Z</a:updated>
Here is the code I have so far.
XNamespace nsW3Atom = "http://www.w3.org/2005/Atom";
XNamespace nsOs = "http://a9.com/-/spec/opensearch/1.1/";
XNamespace nsZune = "http://schemas.zune.net/calatog/apps/2008/02";
XDocument doc =
new XDocument(
// new XDeclaration("1.0", "utf-8", "no"),
new XElement("feed",
new XAttribute("a", nsW3Atom),
new XAttribute("os", nsOs),
new XAttribute("os2", nsZune),
new XElement(XNamespace.Xmlns + "link", new XAttribute("rel", "prev"), new XAttribute("type", "application/atom+xml")),
new XElement(XNamespace.Xmlns + "link", new XAttribute("rel", "next"), new XAttribute("type", "application/atom+xml")),
new XElement(XNamespace.Xmlns + "link", new XAttribute("rel", "self"), new XAttribute("type", "application/atom+xml"))));
Thank you in advance for the help!

XNamespace a="http://www.w3.org/2005/Atom";
XNamespace os = "http://a9.com/-/spec/opensearch/1.1/";
XNamespace def = "http://schemas.zune.net/catalog/apps/2008/02";
var doc =
new XDocument(new XElement(a + "feed",
new XAttribute(XNamespace.Xmlns + "a", a),
new XAttribute(XNamespace.Xmlns + "os", os),
new XAttribute("xmlns", def)));
then if You want to use the a Namespace, prefix any element with a+

When creating the attributes use the xmlns: prefix.
new XAttribute("xmlns:a", nsW3Atom),
new XAttribute("xmlns:os", nsOs),
new XAttribute("xmlns:os2", nsZune)

Related

Error parsing xml syntax error

I have the following code below. I am getting an error "the character ':' hexadecimal value 0x3A cannot be included in a name" Can anyone tell me how to fix this?
Thanks Below is the entire code
public static XDocument GenerateXMLSpreadSheet(DataTable tbl)
{
new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XProcessing**Instruction("mso-application", "Excel.Sheet"),
new XElement("Workbook",
new XAttribute("xmlns", "urn:schemas-microsoft-com:office:spreadsheet"),
new XAttribute("xmlns:ss", "urn:schemas-microsoft-
com:office:spreadsheet"),
new XElement("Worksheet", new XAttribute("ss:Name",
tbl.TableName),
new XElement("Table", GetRows(tbl)
)
)
)
);
return xmlssDoc;
)
public static Object[] GetRows(DataTable tbl)
{
// generate XElement rows for each row in the database.
// generate from the bottom-up.
// start with the cells.
XElement[] rows = new XElement[tbl.Rows.Count];
int r = 0;
foreach (DataRow row in tbl.Rows)
{
// create the array of cells to add to the row:
XElement[] cells = new XElement[tbl.Columns.Count];
int c = 0;
foreach (DataColumn col in tbl.Columns)
{
cells[c++] =
new XElement("Cell",
new XElement("Data", new XAttribute("ss:Type", "String"),
new XText(row[col].ToString())));
}
rows[r++] = new XElement("Row", cells);
}
// return the array of rows.
return rows;
}
Basically, that's not how you handle namespaces in LINQ to XML. You never specify a string with a colon in - instead, you build up an XName from an XNamespace and a string.
The good news is that LINQ to XML handling of namespaces is simple. Here's a complete example:
using System;
using System.Xml.Linq;
public class Test
{
static void Main(string[] args)
{
XNamespace ns = "urn:schemas-microsoft-com:office:spreadsheet";
var doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XProcessingInstruction("mso-application", "Excel.Sheet"),
new XElement(ns + "Workbook",
new XAttribute("xmlns", ns),
new XAttribute(XNamespace.Xmlns + "ss", ns),
new XElement(ns + "Worksheet",
new XAttribute(ns + "Name", "my-table-name"),
new XElement(ns + "Table")
)
)
);
Console.WriteLine(doc);
}
}
Output (reformatted for clarity):
<?mso-application Excel.Sheet?>
<ss:Workbook
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<ss:Worksheet ss:Name="my-table-name">
<ss:Table />
</ss:Worksheet>
</ss:Workbook>
Note how you need to specify the namespace for all the elements and attributes.
Because you've specified an explicit prefix for the namespace, LINQ to XML uses it everywhere. If you remove this part:
new XAttribute(XNamespace.Xmlns + "ss", ns)
... then the namespace for elements will be defaulted, and LINQ to XML will generate a prefix for the attributes that need it explicitly specified (as attributes don't default their namespaces).
Then the output is (for example):
<?mso-application Excel.Sheet?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet p2:Name="my-table-name" xmlns:p2="urn:schemas-microsoft-com:office:spreadsheet">
<Table />
</Worksheet>
</Workbook>
The problem is how you defined namespaces.
To work with namespaces you may get one by calling XNamespace.Get("the namespace") and using this everywhere you want.
And for xmlns you may use static property XNamespace.Xmlns.
So the final code will look like:
new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XProcessingInstruction("mso-application", "Excel.Sheet"),
new XElement("Workbook",
new XAttribute("xmlns", ns),
new XAttribute(XNamespace.Xmlns + "ss", ns),
new XElement("Worksheet", new XAttribute(ns + "Name",
tbl.TableName),
new XElement("Table", GetRows(tbl)
)
)
)
);

How to add xmlns to xml document?

I'm trying to create a fairly simple XML document that looks like this.
<?xml version="1.0" encoding="UTF-8"?>
<employees xmlns="http://website.com/xsd/MQ">
<employee>
<id>00122731</id>
<first-name>LUIS</first-name>
<last-name>GARCIA</last-name>
<subarea>4100</subarea>
<cost-center>904</cost-center>
<email-address>L.GARCIA#EMAIL.COM</email-address>
</employee>
</employees>
I was able to get the basics by using this code but I need to add the xmlns attribute and I'm not figuring out how to do that.
var xmlDoc = new XElement("employees",
from e in listEmployees
select new XElement("employee",
new XElement("id", e.EmployeeId),
new XElement("first-name", e.FirstName),
new XElement("last-name", e.LastName),
new XElement("subarea", e.SubArea),
new XElement("cost-center", e.CostCenter),
new XElement("email-address", e.EmailAddress)));
This is my attempt to add it but I get an error that this would cause and invalid structure.
XDocument xmlDoc = new XDocument(
new XElement("employees",
new XAttribute("xmlns", "http://website/xsd/MQ")),
from e in listEmployees
select new XElement("employee",
new XElement("id", e.EmployeeId),
new XElement("first-name", e.FirstName),
new XElement("last-name", e.LastName),
new XElement("subarea", e.SubArea),
new XElement("cost-center", e.CostCenter),
new XElement("email-address", e.EmailAddress))
);
UPDATE
Based on the link provided below this is what I came up with that worked.
XNamespace ns = "http://website/xsd/MQ";
var xmlDoc = new XElement(ns + "employees",
from e in listEmployees
select new XElement("employee",
new XElement("id", e.EmployeeId),
new XElement("first-name", e.FirstName),
new XElement("last-name", e.LastName),
new XElement("subarea", e.SubArea),
new XElement("cost-center", e.CostCenter),
new XElement("email-address", e.EmailAddress)));
You need to include the namespace on all of your elements, not just the top one:
XNamespace ns = "http://website/xsd/MQ";
var xmlDoc = new XElement(ns + "employees",
from e in listEmployees
select new XElement(ns + "employee",
new XElement(ns + "id", e.EmployeeId),
new XElement(ns + "first-name", e.FirstName),
new XElement(ns + "last-name", e.LastName),
new XElement(ns + "subarea", e.SubArea),
new XElement(ns + "cost-center", e.CostCenter),
new XElement(ns + "email-address", e.EmailAddress)
)
);
If that's too repetitive for you, you could make a convenience method:
XNamespace ns = "http://website/xsd/MQ";
private static XElement MQElement(string name, object contents)
{
return new XElement(ns + name, contents);
}
then use it:
var xmlDoc = MQElement("employees",
from e in listEmployees
select MQElement("employee",
MQElement("id", e.EmployeeId),
MQElement("first-name", e.FirstName),
MQElement("last-name", e.LastName),
MQElement("subarea", e.SubArea),
MQElement("cost-center", e.CostCenter),
MQElement("email-address", e.EmailAddress)
)
);
One more option to achieve same result is to construct XElement ignoring namespaces completely and then add them in separate code:
foreach (XElement e in xmlDoc.DescendantsAndSelf())
{
if (e.Name.Namespace == "")
{
e.Name = ns + e.Name.LocalName;
}
}

How can I add an XSL stylesheet inside an XML file with C#?

I have a C# console application that runs and adds the following to the a file:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<qf:VisualTemplate xmlns:qf="http://www.Qnomy.com/Templates" version="1.0" description="test doc">
<qf:Styles />
<qf:Parameters />
<qf:SampleData />
<qf:Design />
</qf:VisualTemplate>
It uses this bit of code to do that:
var doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(ns + "VisualTemplate",
new XAttribute(XNamespace.Xmlns + "qf", url),
new XAttribute("version", "1.0"),
new XAttribute("description", "test doc"),
new XElement(ns + "Styles"),
new XElement(ns + "Parameters"),
new XElement(ns + "SampleData"),
new XElement(ns + "Design")
)
);
I need to also add an embedded xsl stylesheet in between the qf:Design node, like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<qf:VisualTemplate xmlns:qf="http://www.Qnomy.com/Templates" version="1.0" description="test doc">
<qf:Styles />
<qf:Parameters />
<qf:SampleData />
<qf:Design>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
</xsl:stylesheet>
</qf:Design>
</qf:VisualTemplate>
I have tried doing it the same way as i created the xml but i cant use xsl as the namespace:
var url2 = "http://www.w3.org/1999/XSL/Transform";
var ns2 = XNamespace.Get(url2);
var d = doc.Descendants(ns + "Design").First();
d.AddBeforeSelf(new XComment("Place your HTML elements here"));
d.Add(
new XElement(ns + "Design",
new XElement(ns2 + "stylesheet",
new XAttribute(XNamespace.Xmlns + "xsl", ""),
new XAttribute("version", "1.0")
)
)
);
Is there any way i can add the xsl stylesheet with C# in the same way as i have done the XML elements?
Based on your expected output XML, the xsl prefix should've been bound to "http://www.w3.org/1999/XSL/Transform", not to empty string :
.....
new XElement(ns2 + "stylesheet",
new XAttribute(XNamespace.Xmlns + "xsl", "http://www.w3.org/1999/XSL/Transform"),
new XAttribute("version", "1.0")
)
.....

C# with XDocument and xsi:schemaLocation

I want to create the following XML.
<?xml version="1.0" encoding="utf-8"?>
<MyNode xsi:schemaLocation="https://MyScheme.com/v1-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://MyScheme.com/v1-0 Sscheme.xsd">
<MyInfo>
<MyNumber>string1</MyNumber>
<MyName>string2</MyName>
<MyAddress>string3</MyAddress>
</MyInfo>
<MyInfo2>
<FirstName>string4</FirstName>
</MyInfo2>
</MyNode>
I'm using this code.
XNamespace xmlns = "https://MyScheme.com/v1-0 Sscheme.xsd";
XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XNamespace schemaLocation = XNamespace.Get("https://MyScheme.com/v1-0");
XDocument xmlDocument = new XDocument(
new XElement(xmlns + "MyNode",
new XAttribute(xsi + "schemaLocation", schemaLocation),
new XAttribute(XNamespace.Xmlns + "xsi", xsi),
new XElement("MyInfo",
new XElement("MyNumber", "string1"),
new XElement("MyName", "string2"),
new XElement("MyAddress", "string3")
),
new XElement("MyInfo2",
new XElement("FirstName", "string4")
)
)
);
xmlDocument.Save("C:\\MyXml.xml");
However, I'm getting xmlns="" inside tags MyInfo and MyInfo2.
Can somebody help me to create the correct XML?
You need to use xmlns XNamespace for all elements, because that is default namespace and it is declared at root level element. Note that descendant elements inherit ancestor default namespace implicitly, unless otherwise specified :
XDocument xmlDocument = new XDocument(
new XElement(xmlns + "MyNode",
new XAttribute(xsi + "schemaLocation", schemaLocation),
new XAttribute(XNamespace.Xmlns + "xsi", xsi),
new XElement(xmlns+"MyInfo",
new XElement(xmlns+"MyNumber", "string1"),
new XElement(xmlns+"MyName", "string2"),
new XElement(xmlns+"MyAddress", "string3")
),
new XElement(xmlns+"MyInfo2",
new XElement(xmlns+"FirstName", "string4")
)
)
);
Dotnetfiddle Demo

c# write xml muitiable atrrtibutes

I am creating xml file with c#, The xml is:
<?xml version="1.0" encoding="utf-8"?>
<Project Title="old one"
Version="1.5.1.0"
Author=""
EmphasisColor1Label=""
EmphasisColor1="#000000"
EmphasisStyle1="---" >
</Project>
my c# code is:
XmlDocument doc = new XmlDocument();
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(decl);
XmlElement ChatMapper = doc.CreateElement("Project");
doc.AppendChild(ChatMapper);
XmlNode xmldocSelect = doc.SelectSingleNode("Project");
//Crteate Attribute
XmlAttribute attra = doc.CreateAttribute("Title");
attra.Value ="old one";
xmldocSelect.Attributes.Append(attra);
XmlAttribute attrb = doc.CreateAttribute("Version");
attrb.Value ="1.5.1.0";
xmldocSelect.Attributes.Append(attrb);
XmlAttribute attrc = doc.CreateAttribute("EmphasisColor1Label");
attrc.Value ="";
xmldocSelect.Attributes.Append(attrc);
XmlAttribute attrd = doc.CreateAttribute("EmphasisColor1");
attrd.Value ="#000000";
xmldocSelect.Attributes.Append(attrd);
XmlAttribute attre = doc.CreateAttribute("EmphasisStyle1");
attre.Value ="---";
xmldocSelect.Attributes.Append(attre);
That is not smart and too long, anyone knows how to make it shorter?
You can use System.Xml.Linq namespace to create xml. Code snippet in C#:
XDocument doc = new XDocument(
new XElement("Project ",
new XAttribute("Title", "old one"),
new XAttribute("Version", "1.5.1.0"),
new XAttribute("Author", ""),
new XAttribute("EmphasisColor1Label", ""),
new XAttribute("EmphasisColor1", "#000000"),
new XAttribute("EmphasisStyle1", "")
)
);
doc.Save("Project.xml");
Using LINQ:-
using System.Xml.Linq;
var xml =
new XElement("Project",
new XAttribute("Title", "old one"),
new XAttribute("Version", "1.5.1.0"),
new XAttribute("Author", ""),
new XAttribute("EmphasisColor1Label", ""),
new XAttribute("EmphasisColor1", "#000000"),
new XAttribute("EmphasisStyle1", "---")
);
xml.Save("Project.xml");
WITHOUT LINQ:-
XmlDocument doc = new XmlDocument();
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(decl);
XmlElement ChatMapper = doc.CreateElement("Project");
ChatMapper.SetAttribute("Title", "old one");
ChatMapper.SetAttribute("Version", "1.5.1.0");
ChatMapper.SetAttribute("EmphasisColor1", "#000000");
ChatMapper.SetAttribute("EmphasisStyle1", "---");
doc.AppendChild(ChatMapper);
doc.Save("project.xml");

Categories