8

So I am still asking questions about this topic :-(

So I create an object, decorate it with the Xml Serialization Attributes, from what I have seen I add an empty namespace to the xml serialization namepsace collections so as not to get the superfluous attributes I did not intend to have.

Edit: The attribute I mean are these:

<url xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns="">

so it gives me two extra attributes.

After further investigation if I change the beginning of the document from:**

writer.WriteStartElement("urlset","http://www.sitemaps.org/schemas/sitemap/0.9");

to

writer.WriteStartElement("urlset");

**Then I do not get the empty xmlns="" attribute in the url tags. This is great BUT I do require that the root element have xmlns="http://www.sitemaps.org/schemas/sitemap/0.9", i.e.:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

But I still get an empty xmlns="" attribute in the serialized type.

[XmlRoot(ElementName = "url", Namespace="")]
public class SitemapNode
{
    [XmlElement(ElementName = "loc")]
    public string Location { get; set; }
    [XmlElement(ElementName = "lastmod")]
    public DateTime LastModified { get; set; }
    [XmlElement(ElementName = "changefreq")]
    public SitemapChangeFrequency ChangeFrequency { get; set; }
    [XmlElement(ElementName = "priority")]
    public decimal Priority { get; set; }

    public SitemapNode()
    {
        Location = String.Empty;
        LastModified = DateTime.Now;
        ChangeFrequency = SitemapChangeFrequency.monthly;
        Priority = 0.5M;
    }

    public SitemapNode(string location, DateTime lastModified, SitemapChangeFrequency changeFrequency, decimal priority)
    {
        Location = location;
        LastModified = lastModified;
        ChangeFrequency = changeFrequency;
        Priority = priority;
    }
}

Then I use the following to append to my XmlWriter:

foreach (uk.co.andrewrea.SitemapNode node in List)
{
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add(String.Empty, String.Empty);
    Serializer.Serialize(Writer, node, ns);
}

This works out fine except I am left with an emtpy xmlns="" like this

<url xmlns="">

Anyone any ideas? Again I can achieve this using the XmlTextWriter and the XmlDocument but I need to achieve it using the XmlWriter.

Any help is greatly appreciated.

2
  • > I add an empty namespace to the xml serialization namepsace collections so as not to get the superfluous attributes I did not intend to have. Can you elaborate on this? What do you mean by superfluous attributes? Commented Mar 5, 2009 at 19:55
  • <url xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema"; xmlns=""> So it gives me two extra attributes. Commented Mar 5, 2009 at 20:33

3 Answers 3

12

This works (you just need them to be in the same namespace and you use the namespaces class so the writter doesn't confuse):

[TestMethod]
public void TestMethod3()
{
    var list = new []{new SitemapNode("1", DateTime.Now, 1), new SitemapNode("2", DateTime.Now.AddDays(1), 2)};
    var serializer = new XmlSerializer(typeof(SitemapNode));
    var st = new MemoryStream();
    using (var writer = XmlWriter.Create(st))
    {
        var ns = new XmlSerializerNamespaces();
        ns.Add("", "test");
        writer.WriteStartElement("test", "test");
        foreach (SitemapNode node in list)
        {
            serializer.Serialize(writer, node, ns);
        }
        writer.WriteEndElement();
    }
    st.Position = 0;
    TestContext.WriteLine(new StreamReader(st).ReadToEnd());
}


[XmlRoot(ElementName = "url", Namespace = "test")]
public class SitemapNode
{
    [XmlElement(ElementName = "loc")]
    public string Location { get; set; }
    [XmlElement(ElementName = "lastmod")]
    public DateTime LastModified { get; set; }
    [XmlElement(ElementName = "priority")]
    public decimal Priority { get; set; }

    public SitemapNode()
    {
        Location = String.Empty;
        LastModified = DateTime.Now;
        Priority = 0.5M;
    }

    public SitemapNode(string location, DateTime lastModified, decimal priority)
    {
        Location = location;
        LastModified = lastModified;
        Priority = priority;
    }
}

And the output is (based on your comments that is what you were looking for):

    <?xml version="1.0" encoding="utf-8"?><test xmlns="test">
<url><loc>1</loc><lastmod>2009-03-05T13:35:54.6468-07:00</lastmod><priority>1</priority></url>
<url><loc>2</loc><lastmod>2009-03-06T13:35:54.6478-07:00</lastmod><priority>2</priority></url></test>
Sign up to request clarification or add additional context in comments.

2 Comments

If I could mark you up 50 points my self I would!! Great post, and thank you for your time in this matter. I really appreciate it! Worked a treat. + 1 + ANSWER :-)
Take this same example and add this property to SitemapNode: [XmlElement(ElementName = "value")] public string Value { get; set; } Why the serializer just IGNORES it?
3

I was having trouble inserting a node into an existing document with multiple namespaces.

No matter what I set the namespace to it would add the xmlns reference attribute every time no matter what. This was breaking something black boxed downstream.

I eventually got around this by doing something like this.

XmlNode newNode = newDoc.SelectSingleNode(xpathQuery, manager);
newNode.Attributes.RemoveAll();   
node.ParentNode.InsertAfter(node.OwnerDocument.ImportNode(newNode, true), node);

Comments

0

Have you tried not specifying the namespace in your XmlRoot attribute?

I.e.:

[XmlRoot(ElementName = "url")]
public class SitemapNode
{ 
...
}

4 Comments

Yes still the same, it outputs an empty xmlns=""
And removing the XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add(String.Empty, String.Empty); as well?
I thought that at first but the output is as follows: <url xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:xsd="w3.org/2001/XMLSchema" xmlns=""> So it gives me two extra attributes.
To add further information when I start the document I write my root element with a namespace. NOW, if I do not write the namespace then subsequent child root nodes do not output an xmlns attribute. How can I give the root element a xmlns attribute but no the child nodes when serializing?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.