How to create XElement with namespaces - c#

I need to generate xml like that:
<urlset xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://blabla</loc>
<video:video>
<video:player allow_embed="yes">http://blablabla</video:player_loc>
</video:video>
</url>
I can't figure out the way to work with namespaces. I can't even create urlset element properly, I'm trying:
XNamespace _defaultNamespace = "http://www.sitemaps.org/schemas/sitemap/0.9";
XNamespace _videoNameSpace = "http://www.google.com/schemas/sitemap-video/1.1";
new XElement("urlset",new XAttribute(_defaultNamespace+"video",_defaultNamespace))
and it generates:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset p1:video="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:p1="http://www.sitemaps.org/schemas/sitemap/0.9">
what's that p1 thing?

Namespace attributes are in xmlns namespace, so you should use
XNamespace.Xmlns+ attributeName for declaring namespaces:
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
XNamespace video = "http://www.google.com/schemas/sitemap-video/1.1";
var urlset = new XElement(ns + "urlset",
new XAttribute(XNamespace.Xmlns + "video", video));
Produces
<urlset xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" />
Complete xml generation will look like:
var urlset = new XElement(ns + "urlset",
new XAttribute(XNamespace.Xmlns + "video", video),
new XElement(ns + "url",
new XElement(ns + "loc", "http:/blabla"),
new XElement(video + "video",
new XElement(video + "player",
new XAttribute("allow_embed", "yes"),
"http:/blabla"))));

Related

Two identical namespaces with dirfferent prefixes in XDocument

So, I try creating Xml document with next code:
XNamespace spr1 = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace ex = "urn:schemas-microsoft-com:office:excel";
XNamespace spr2 = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace rec = "http://www.w3.org/TR/REC-html40";
var xworkbook = new XElement(spr1 + "Workbook");
xworkbook.Add(new XAttribute(XNamespace.Xmlns + "x", ex));
xworkbook.Add(new XAttribute(XNamespace.Xmlns +"ss", spr2));
xworkbook.Add(new XAttribute(XNamespace.Xmlns + "html", rec));
This code make next xml:
<ss:Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
<!--Xml body-->
</ss:Workbook>
But I expect this:
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
</Workbook>
How to build Workbook element without "ss" prefix and with needed "xmlns" attribute?
LINQ to XML uses the namespace prefix that is closest as it looks through all the attributes in reverse order from the current element to the root. So if you add the default namespace explicitly at the end, then Workbook will use that and not the ss prefix.
XNamespace ss = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace ex = "urn:schemas-microsoft-com:office:excel";
XNamespace html = "http://www.w3.org/TR/REC-html40";
var workbook = new XElement(
ss + "Workbook",
new XAttribute(XNamespace.Xmlns + "x", ex),
new XAttribute(XNamespace.Xmlns + "ss", ss),
new XAttribute(XNamespace.Xmlns + "html", html),
new XAttribute("xmlns", ss)
);
This gives you the XML below:
<Workbook xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" />
As stated in the comments, the two documents in your question are semantically the same. Any XML parser shouldn't care about the difference between the two documents.
I usually do it like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"" +
" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"" +
" xmlns:html=\"http://www.w3.org/TR/REC-html40\">" +
"</Workbook>";
XDocument doc = XDocument.Parse(xml);
XElement workbook = (XElement)doc.FirstNode;
XNamespace ssNs = workbook.GetNamespaceOfPrefix("ss");
XElement worksheet = new XElement(ssNs + "Worksheet");
workbook.Add(worksheet);
}
}
}

Namespace with colon as attribute of xml file in C#

I want to generate a xml code like below example:-
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns ="abc.xyz.xsd" xmlns:xsi="http://namespace">
</Root>
My C# code is like below:
XNamespace xsi = "http://namespace";
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement("Root",
new XAttribute("xmlns", "abc.xyz.xsd"),
new XAttribute(XNamespace.Xmlns + "xsi", xsi)
);
This code gives error while saving. What am I doing wrong?
You can use with single namespace
XNamespace xsi = "http://namespace";
XDocument doc1 = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement(xsi + "Root",
new XAttribute("xmlns", "abc.xyz.xsd"),
new XAttribute(XNamespace.Xmlns + "xsi", "http://namespace"),
new XElement(xsi + "Child",
new XElement(xsi + "DifferentChild", "other content")
)
));
See this for reference https://msdn.microsoft.com/en-us/library/bb387075.aspx
The output will look like this
<?xml version="1.0" encoding="utf-8"?>
<xsi:Root xmlns="abc.xyz.xsd" xmlns:xsi="http://namespace">
<xsi:Child>
<xsi:DifferentChild>other content</xsi:DifferentChild>
</xsi:Child>
</xsi:Root>
You should add your Root element with namespace (namespace + "Root") since you're using namespaces.
Like this:
XNamespace xsi = "http://namespace";
XNamespace ns = "abc.xyz.xsd";
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement(ns + "Root",
new XAttribute("xmlns", ns),
new XAttribute(XNamespace.Xmlns + "xsi", xsi)));
See MSDN article concerning creation of documents having namespaces.

Need help creating XML Document with XDocument

I am having trouble creating an XML document using LINQ.
The XML file I need to create has a root element of "ClinicalDocument".
The XML needs to be as follows
<?xml version="1.0" encoding="utf-8"?>
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:hl7-org:v3"
xmlns:voc="urn:hl7-org:v3/voc"
xmlns:sdtc="urn:hl7-org:sdtc">
<!-- Rest of the document here. -->
</ClinicalDocument>
The code I have in trying to do this is
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
XDeclaration dec = new XDeclaration("1.0", "UTF-8", null);
XDocument xDoc = new XDocument(dec,null);
XElement cDoc = new XElement("ClinicalDocumnet");
xDoc.Add(cDoc);
cDoc.Add(new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName));
cDoc.Add(new XAttribute("xmlns","urn:hl7-org:v3"));
cDoc.Add(new XAttribute(XNamespace.Xmlns + "stdc","urn:hl7-org:sdtc"));
cDoc.Add(new XAttribute(XNamespace.Xmlns + "voc","urn:hl7-org:v3/voc"));
xDoc.Save("C:\\test\\test.xml");
I get an exception when trying to save the file.
{"The prefix '' cannot be redefined from '' to 'urn:hl7-org:v3' within the same start element tag."}
XNamespace ns = "urn:hl7-org:v3";
xDoc = new XDocument(dec, null);
cDoc = new XElement(ns + "ClinicalDocument");
xDoc.Add(cDoc);
cDoc.Add(new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"));
cDoc.Add(new XAttribute(XNamespace.Xmlns + "stdc","urn:hl7-org:sdtc"));
cDoc.Add(new XAttribute(XNamespace.Xmlns + "voc","urn:hl7-org:v3/voc"));

Adding and validating a namespaced attribute value using XAttribute

I want to programmatically create a "dcterms:type" element with a namespaced attribute and attribute value using XObjects. The target xml is as follows:
<metadata
xmlns="http://example.org/myapp/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.org/myapp/ http://example.org/myapp/schema.xsd"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/">
...
<dcterms:type xsi:type="dcterms:URI">test</dcterms:type>
...
</metadata>
I have tried:
XNamespace dcterms= XNamespace.Get("http://purl.org/dc/terms/");
XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XNamespace dc = XNamespace.Get("http://purl.org/dc/elements/1.1/");
XAttribute xsiAttribute = new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName);
XAttribute dcAttribute = new XAttribute(XNamespace.Xmlns + "dc", dc.NamespaceName);
XAttribute dcmitypeAttribute = new XAttribute(XNamespace.Xmlns + "dcterms", dcterms.NamespaceName);
...
XElement typeElement = new XElement(dc + "type", "test");
XAttribute typeAttribute = new XAttribute(xsi + "type", dcterms + "URI");
typeElement.Add(typeAttribute);
But this produces:
<dc:type xsi:type="{http://purl.org/dc/terms/}Text">test</dc:type>
... which is wrong and, of course, does not validate. I have also tried hard-coding the value:
XAttribute typeAttribute = new XAttribute(xsi + "type", #"dcterms:URI");
This produces the correct xml, but returns "This is an invalid xsi:type 'http://purl.org/dc/terms/:Text'." when validated via XDocument.Validate().
Ideas?

Add namespaces with and without names to an XElement

I need so generate XML like the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<url>
<loc>http://www.xyz.eu/</loc>
<lastmod>2010-01-20T10:56:47Z</lastmod>
<changefreq>daily</changefreq>
<priority>1</priority>
</url>
<url>
<loc>http://www.xyz.eu/2/</loc>
<lastmod>2009-10-13T10:20:03Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>http://www.xyz.eu/3/</loc>
<lastmod>2009-10-13T10:19:09Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
</urlset>
I cant seem to figure out how to add the namespace with no name without putting ' xmlns="" ' in all the url tags.
my code:
XNamespace blank = XNamespace.Get(#"http://www.sitemaps.org/schemas/sitemap/0.9");
XNamespace xsi = XNamespace.Get(#"http://www.w3.org/2001/XMLSchema-instance");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(blank + "urlset",
//new XAttribute(XNamespace.Xmlns +"", blank),
new XAttribute(XNamespace.Xmlns + "xsi", xsi),
// This private method loops through the dictionary and creates all the page nodes
GetSiteMapChildren(pageIdVersionDic, site.Url)
));
Any ideas? Thanks
You need to declare the "blank" namespace as the default namespace. For example this works just fine:
XNamespace blank = XNamespace.Get(#"http://www.sitemaps.org/schemas/sitemap/0.9");
XNamespace xsi = XNamespace.Get(#"http://www.w3.org/2001/XMLSchema-instance");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(blank + "urlset",
new XAttribute("xmlns", blank.NamespaceName),
new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
new XElement(blank + "url",
new XElement(blank + "loc", "http://www.xyz.eu/"),
new XElement(blank + "lastmod", "2010-01-20T10:56:47Z"),
new XElement(blank + "changefreq", "daily"),
new XElement(blank + "priority", "1"))
));
Console.WriteLine(doc.ToString());

Categories

Resources