1

I am attempting to create an XML document through the application of attributes on fields/properties ([XmlAttribute], [XmlElement], etc.) My problem is that I have a requirement that I attach an additional attribute to a primitive datatype in the style of:

<document xmlns:dt="urn:schemas-microsoft-com:datatypes" >
  <binary addAttribute="X" dt:dt="bin.base64">
    [... binary ...]
  </binary>
</document>

I'm making use of code like the following:

[Serializable]
public class Document {
    [XmlElement]
    public BinaryObject Binary { get; set; }
}

[Serializable]
public class BinaryObject {
    [XmlText(DataType = "base64Binary")]
    public byte[] Binary { get; set; }

    [XmlAttribute]
    public int AddAttribute { get; set; }
}

public class XmlExample {
    public static void Main(string[] args)
    {
        Document document = new Document();
        document.Binary = new BinaryObject();
        document.Binary.Binary = File.ReadAllBytes(@"FileName");
        document.Binary.AddAttribute = 0;

        XmlSerializer serializer = new XmlSerializer(typeof(Document));

        serializer.Serialize(Console.Out, document);
        Console.ReadLine();
    }
}

This, however, provides the following output:

<document>
  <binary addAttribute="X">
    [... binary ...]
  </binary>
</document>

If I attempt to move the byte[] Binary to the Document class instead I can get the xmlns:dt="..." as expected but I cannot attach the arbitrary addAttribute when I do so (unless I missed something obvious.) This was incorrect; I misread something in the XML that I was getting out of the XML. The xmlns:dt element was not added in this case.

The question is: Can I do this (have both the DataType and the addAttribute) exclusively through C# attributes?

3
  • The attributes with colons are namespaces. Commented Dec 9, 2015 at 0:40
  • @jdweng Yes, they are. I think I made the mistake of assuming (or thought I saw during my testing) that the DataType = "base64Binary" would set these namespace attributes as well. I'm going to think about it and update the question. Commented Dec 9, 2015 at 16:00
  • @jdweng I've updated the question with a correction and added the answer that satisfied my constraints. Thank you; your comment here helped me to think about it in terms of a namespace attribute rather than an attribute property (as I had.) Commented Dec 9, 2015 at 17:52

2 Answers 2

1

The answer to this question came partially from here: XmlSerializer attribute namespace for element type dt:dt namespace. The DataType = "base64Binary" does not apply the xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64" to the element that it is attached to. An attribute has to be added to the BinaryObject that provides the dt:dt = "bin.base64" with the correct name space.

Final Code

[Serializable]
public class Document {
    public BinaryObject Binary { get; set; }
}

[Serializable]
public class BinaryObject {
    [XmlText]
    public byte[] Binary { get; set; }

    [XmlAttribute]
    public int AddAttribute { get; set; }

    // Adds the dt:dt object to the correct name space.
    [XmlAttribute("dt", Namespace = "urn:schemas-microsoft-com:datatypes")]
    public string DataType { get; set; }

    public BinaryObject() { DataType = "bin.base64"; }
}


public class XmlExample {
    public static void Main(string[] args)
    {
        XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();

        // Adds the needed namespace to the document.
        namespaces.Add("dt", "urn:schemas-microsoft-com:datatypes");

        Document document = new Document();
        document.Binary = new BinaryObject();
        document.Binary.Binary = new byte[]{0,1,2,3,4,5,6,7,8,9};
        document.Binary.AddAttribute = 0;

        XmlSerializer serializer = new XmlSerializer(typeof(Document));

        serializer.Serialize(Console.Out, document, namespaces);
        Console.ReadLine();
    }
}

Final Output

<Document xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <Binary AddAttribute="0" dt:dt="bin.base64">AAECAwQFBgcICQ==</Binary>
</Document>
Sign up to request clarification or add additional context in comments.

Comments

0

Try this

using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    [XmlRoot("Document")]
    public class Document
    {
        [XmlText(DataType = "base64Binary")]
        public byte[] Binary { get; set; }
        [XmlAttribute]
        public int AddAttribute { get; set; }
    }

}
​

1 Comment

This moves the BinaryObject's values into the Document class and changes the node structure (not that this would prevent me adapting it if it produced the needed attributes); it does not cause the return of both the AddAttribute and xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64".

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.