Reputation: 66
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?
Upvotes: 1
Views: 1594
Reputation: 66
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>
Upvotes: 1
Reputation: 34421
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; }
}
}
Upvotes: 0