tags:

views:

3084

answers:

2

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 the xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" i.e. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;

But I still get an empty xmlns="" atttribute 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.

Andrew

A: 

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

I.e.:

[XmlRoot(ElementName = "url")]
public class SitemapNode
{ 
...
}
ck
Yes still the same, it outputs an empty xmlns=""
REA_ANDREW
And removing the XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add(String.Empty, String.Empty);as well?
ck
I thought that at first but the output is as follows:<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.
REA_ANDREW
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?
REA_ANDREW
+3  A: 

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>
eglasius
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 :-)
REA_ANDREW
Take this same example and add this property to SitemapNode:[XmlElement(ElementName = "value")] public string Value { get; set; }Why the serializer just IGNORES it?
andrecarlucci