1

Good day all,

I have trouble adding namespaces correctly to my XML. Both the parent and child elements have the own namespaces. When restructure the code I have gotten mixed results. My sample code below:

using System;
using System.IO;
using System.Xml.Serialization;

namespace XmlSerializationExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var grandchild = new grandchild_element { Value = "randomResults" };
            var child = new child_element { grandchildElement = grandchild };
            var parent = new parent_element { childElement = child };

            var serializer = new XmlSerializer(typeof(parent_element), "www.testing.com");
            var namespaces = new XmlSerializerNamespaces(new[]
            {
                new XmlQualifiedName("xsi", "http://www.w3.org/2001/XMLSchema-instance")
            });
            var settings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent = true,
                Encoding = System.Text.Encoding.UTF8
            };

            string xmlOutPut = @"C:\Users\[user]\Desktop\xml_test_file_" + DateTime.Now.ToString("HHmmss") + ".xml";

            using (var fileStream = new FileStream(xmlOutPut, FileMode.Create))
            using (var xmlWriter = XmlWriter.Create(fileStream, settings))
            {
                xmlWriter.WriteStartElement("parentElement", "www.testing.com");

                serializer.Serialize(xmlWriter, parent, namespaces);

                xmlWriter.WriteEndElement();
            }
        }
    }

    [XmlRoot(ElementName = "parentElement", Namespace = "www.testing.com")]
    public class parent_element
    {
        public child_element childElement { get; set; }
    }

    public class child_element
    {
        [XmlElement(ElementName = "grandchildElement")]
        public grandchild_element grandchildElement { get; set; }

        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string xsi = "http://www.w3.org/2001/XMLSchema-instance";

        [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string type = "text_type";
    }

    public class grandchild_element
    {
        [XmlText]
        public string Value { get; set; }
    }
}

My results have been

<parentElement xmlns="www.testing.com">

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

    <childElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="text_type">

      <grandchildElement>randomResults</grandchildElement>

    </childElement>

  </parentElement>

</parentElement>

The result I am looking for is without the second parentElement. Something that looks like what is below

<parentElement xmlns="www.testing.com">

    <childElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="text_type">

      <grandchildElement>randomResults</grandchildElement>

    </childElement>

</parentElement>

Any help would be great. I know I am over looking something but I am not sure what. Huge thanks in advance

2
  • new XmlSerializer(typeof(child_element) probably Commented Apr 24, 2023 at 23:36
  • Just tried changing var serializer = new XmlSerializer(typeof(parent_element), "www.testing.com") to var serializer = new XmlSerializer(typeof(child_element), "www.testing.com")Unfortunately it didn't work. Still testing it and I think it maybe something with the var namespaces or WriteStartElement Commented Apr 25, 2023 at 0:08

1 Answer 1

1
  • Remove below 2 calls to the xmlWriter.
xmlWriter.WriteStartElement("parentElement", "www.testing.com");

xmlWriter.WriteEndElement();
  • You don't need the XmlSerializerNamespaces setup.

  • Remove below xsi property from the child_element class.

[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string xsi = "http://www.w3.org/2001/XMLSchema-instance";
  • For deserialization purposes, do add a [XmlType("text_type")] attribute to the child_element class.

Your model classes will look like below.

[XmlRoot(ElementName = "parentElement", Namespace = "www.testing.com")]
public class parent_element
{
    public child_element childElement { get; set; }
}

[XmlType("text_type")]
public class child_element
{
    [XmlElement(ElementName = "grandchildElement")]
    public grandchild_element grandchildElement { get; set; }

    [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string type = "text_type";
}

public class grandchild_element
{
    [XmlText]
    public string Value { get; set; }
}

The following code shows how to do the serialization.

var grandchild = new grandchild_element { Value = "randomResults" };
var child = new child_element { grandchildElement = grandchild };
var parent = new parent_element { childElement = child };

var serializer = new XmlSerializer(typeof(parent_element));
var settings = new XmlWriterSettings
{
    OmitXmlDeclaration = true,
    Indent = true,
    Encoding = System.Text.Encoding.UTF8,
};

string xmlOutPut = @"C:\Users\[user]\Desktop\xml_test_file_" + DateTime.Now.ToString("HHmmss") + ".xml";

using (var fileStream = new FileStream(xmlOutPut, FileMode.Create))
using (var xmlWriter = XmlWriter.Create(fileStream, settings))
{
    serializer.Serialize(xmlWriter, parent);
}

This will result in the following xml.

<parentElement 
    xmlns="www.testing.com"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <childElement xsi:type="text_type">
    <grandchildElement>randomResults</grandchildElement>
  </childElement>
</parentElement>
Sign up to request clarification or add additional context in comments.

8 Comments

Your xml is stll not valid
it can not be deserialized to a c# class. I will remove down vote as soon as you fix xml.Compiller gives an error <parentElement xmlns='www.testing.com'> was not expected.
@Serge On deserialization an error indeed occurred The specified type was not recognized: name='text_type', namespace='www.testing.. The deserialization now succeeds by adding a [XmlType("text_type")] on the child_element class. I've updated my post. Thanks for noticing.
I upvoted your answer but is still not completely valid. I don' t know XML since it is an ancient technology but I am using Visual Studio to check it. I copy xml text and if it is completely valid I can see VS editor option "Paste XML as class" but in this case I don't see this option
@Serge Hi, given your valid previous remark, I gave above code a full serialize and deserialize roundtrip, and don't hit any exceptions anymore.
|

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.