Xelement Namespaces (How To)

XElement namespaces (How to?)

It's really easy in LINQ to XML:

XNamespace ns = "sphinx";
XElement element = new XElement(ns + "docset");

Or to make the "alias" work properly to make it look like your examples, something like this:

XNamespace ns = "http://url/for/sphinx";
XElement element = new XElement("container",
new XAttribute(XNamespace.Xmlns + "sphinx", ns),
new XElement(ns + "docset",
new XElement(ns + "schema"),
new XElement(ns + "field", new XAttribute("name", "subject")),
new XElement(ns + "field", new XAttribute("name", "content")),
new XElement(ns + "attr",
new XAttribute("name", "published"),
new XAttribute("type", "timestamp"))));

That produces:

<container xmlns:sphinx="http://url/for/sphinx">
<sphinx:docset>
<sphinx:schema />
<sphinx:field name="subject" />
<sphinx:field name="content" />
<sphinx:attr name="published" type="timestamp" />
</sphinx:docset>
</container>

How create XElement with specific namespace?

<name:Example xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> is not namespace well-formed as the prefix name is not declared. So constructing that with an XML API is not possible. What you can do is construct the following namespace well-formed XML

<name:Example xmlns:name="http://example.com/name" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />

with the code

//<name:Example xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:name="http://example.com/name"></name:Example>

XNamespace name = "http://example.com/name";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";

XElement example = new XElement(name + "Example",
new XAttribute(XNamespace.Xmlns + "name", name),
new XAttribute(XNamespace.Xmlns + "xsi", xsi));

Console.WriteLine(example);

How to create XElement with namespaces

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

How do I set namespace attributes on an XElement

It took scouring a lot of blogs but I finally came up with what I think is the "right" way to do this:

XNamespace ns = @"http://www.myapp.com/resource";
XNamespace xsi = @"http://www.w3.org/2001/XMLSchema-instance";

var root = new XElement(ns + "root",
new XAttribute(XNamespace.Xmlns+"xsi", xsi.NamespaceName),
new XAttribute(xsi + "schemaLocation", @"http://www.myapp/resource TheResource.xsd")
);

How to add a namespace when parsing string to Xelement?


XNamespace Namespace = "http://mynamespace";
string defaultXml = "<ReferResult><Text> Testing Referred</Text></ReferResult>";

XElement myXml = XElement.Parse(defaultXml);
myXml.Name = Namespace + myXml.Name.LocalName;

//If you want the children to have the same namespace, use the following.
//If you want only the parent to have the namespace, omit the code bellow
foreach(var element in myXml.Descendants()){
element.Name = Namespace + element.Name.LocalName;
}

//Output:
//<ReferResult xmlns="http://mynamespace">
// <Text> Testing Referred</Text>
//</ReferResult>

Edit: As OP's requested in the comments, to remove the namespaces, just use the same code, but omiting the namespace part:

myXml.Name = myXml.Name.LocalName;
foreach(var element in myXml.Descendants()){
element.Name = element.Name.LocalName;
}

Get element from XElement with multiple namespaces

Specify the first namespace instead of ns2

var xe = XElement.Parse(response);
XNamespace ns = "http://mastercard.com/sd/pc/service";
var obj = (string)xe.Descendants(ns + "company").Single();
Console.WriteLine(obj);

Add namespaces with and without names to an XElement

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

Add XElement that uses namespace

There are two points. First, your Line1 element is qualified with a namespace and apply-templates is not, while what you want is the reverse. That's your own doing: you add namespace in new XElement(this.nsXsl + node, … (node, I presume, is "Line1"), and you omit to do so in new XElement(fork, … (obviously, fork is "apply-templates"). Just move this.nsXsl + from former to the latter spot.

Second, you say you'd prefer that XSLT namespace be denoted by a prefix, xsl. Binding between a prefix and namespace is set by declaration expressed in the form of an attribute of a special form, new XAttribute(XNamespace.Xmlns + prefix, namespaceUri) (you actually do that in your first code snippet). This binding is valid in the element where it is declared and all nested elements, unless overset by another declaration. When XML writer emits an element with a namespace-qualified name, it detects that that namespace is bound to a prefix and uses that prefix (e. g., in your first code snippet, namespace http://www.w3.org/1999/XSL/Transform is bound to prefix xsl, so XML writer adds the xsl: prefix to all nested elements). If XML writer finds out that a used namespace is not bound to a prefix, it emits the default namespace declaration attribute, xmlns="namespace" for you (note that default namespace only affects elements, not attributes).

From the viewpoint of XML information model, the following three snippets are equivalent:

<template match="/shiporder/shipto" xmlns="http://www.w3.org/1999/XSL/Transform">
<Line1 xmlns="">
<apply-templates select="city" xmlns="http://www.w3.org/1999/XSL/Transform" />
</Line1>
</template>

<xsl:template match="/shiporder/shipto" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<Line1>
<xsl:apply-templates select="city" />
</Line1>
</template>

<weird:template match="/shiporder/shipto" xmlns:weird="http://www.w3.org/1999/XSL/Transform">
<Line1>
<weird:apply-templates select="city" />
</Line1>
</template>

How to query XElement with two namespaces

Try Descendants() instead of Elements():

XElement x = XElement.Load(responseReader);
XNamespace ns = "tag:foo.com,2008:/my/data";
var status = x.Descendants(ns + "Status").FirstOrDefault().Value;


Related Topics



Leave a reply



Submit