Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I need to generate the following XML during serialization: (fragment)

<IncidentEvent a:EventTypeText="Beginning" xmlns:a="http://foo">
  <EventDate>2013-12-18</EventDate>
  <EventTime>00:15:28</EventTime>
</IncidentEvent>

The class in question looks like this:

public class IncidentEvent
{
    public string EventDate { get; set; }
    public string EventTime { get; set; }

    [XmlAttribute("EventTypeText", Namespace = "http://foo")]
    public string EventTypeText { get; set; }

}

It appears that the serializer is noticing that the namespace is already declared in an xmlns: at the root and is ignoring my attribute. I also tried the following:

[XmlRoot(Namespace = "http://foo")]
public class IncidentEvent
{
    public string EventDate { get; set; }
    public string EventTime { get; set; }

    private XmlSerializerNamespaces _Xmlns;

    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces Xmlns
    {
        get
        {
            if (_Xmlns == null)
            {
                _Xmlns = new XmlSerializerNamespaces();
                _Xmlns.Add("ett", "http://foo");
            }

            return _Xmlns;
        }

        set
        {
            _Xmlns = value;
        }
    }


    [XmlAttribute("EventTypeText", Namespace = "http://foo")]
    public string EventTypeText { get; set; }

}

This results in the following XML:

  <ett:IncidentEvent EventTypeText="Beginning" xmlns:ett="http://foo">
    <ett:EventDate>2013-12-18</ett:EventDate>
    <ett:EventTime>00:15:28</ett:EventTime>
  </ett:IncidentEvent>

Which is not what I want. The element shouldn't be prefixed, the attribute should be. What is needed to get the serializer to understand what I want?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
612 views
Welcome To Ask or Share your Answers For Others

1 Answer

This may be a bug in XmlSerializer.

As you have noticed, even when XmlAttributeAttribute.Namespace is set explicitly, the attribute will not be prefixed in certain situations. From testing, this appears to happen when the attribute namespace happens to be the same as the namespace of the element currently being written.

For instance:

[XmlRoot(Namespace = "http://foo")]
public class IncidentEvent
{
    [XmlAttribute("EventTypeText", Namespace = "http://foo")]
    public string EventTypeText { get; set; }
}

Serializes to the following XML:

<q1:IncidentEvent EventTypeText="an attribute" xmlns:q1="http://foo" />

And since the attribute is unprefixed, it's actually not in any namespace, as is explained in the XML standard: The namespace name for an unprefixed attribute name always has no value.

However, the following:

[XmlRoot(Namespace = "http://foo")]
public class IncidentEvent
{
    [XmlAttribute("EventTypeText", Namespace = "http://bar")]
    public string EventTypeText { get; set; }
}

Serializes with the attribute correctly prefixed:

<q1:IncidentEvent p1:EventTypeText="an attribute" xmlns:p1="http://bar" xmlns:q1="http://foo" />

The workaround is to explicitly set [XmlAttribute(Form = XmlSchemaForm.Qualified)]. Thus:

[XmlRoot(Namespace = "http://foo")]
public class IncidentEvent
{
    [XmlAttribute("EventTypeText", Namespace = "http://foo", Form = XmlSchemaForm.Qualified)]
    public string EventTypeText { get; set; }
}

Serializes to

<q1:IncidentEvent q1:EventTypeText="an attribute" xmlns:q1="http://foo" />

as required.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...