Caverman
Caverman

Reputation: 3707

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>[email protected]</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)));

Upvotes: 0

Views: 181

Answers (2)

Oleksandr Kobylianskyi
Oleksandr Kobylianskyi

Reputation: 3380

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

Upvotes: 0

JLRishe
JLRishe

Reputation: 101672

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

Upvotes: 2

Related Questions