diff --git a/Gu.Xml.Tests/XmlTests.Properties.cs b/Gu.Xml.Tests/XmlTests.Properties.cs
index ab2f54e..3df2a0c 100644
--- a/Gu.Xml.Tests/XmlTests.Properties.cs
+++ b/Gu.Xml.Tests/XmlTests.Properties.cs
@@ -85,6 +85,30 @@ public void XmlIgnoreAttribute()
Assert.AreEqual(expected, actual);
}
+ [Test]
+ public void XmlAttributeAttribute()
+ {
+ var with = new WithXmlAttribute { Value = 1 };
+ var expected = "" + Environment.NewLine +
+ "" + Environment.NewLine +
+ "";
+
+ var actual = Xml.Serialize(with);
+ Assert.AreEqual(expected, actual);
+ }
+
+ [Test]
+ public void XmlAttributeAttributeExplicitName()
+ {
+ var with = new WithXmlAttributeExplicitName { Value = 1 };
+ var expected = "" + Environment.NewLine +
+ "" + Environment.NewLine +
+ "";
+
+ var actual = Xml.Serialize(with);
+ Assert.AreEqual(expected, actual);
+ }
+
public class WithGetSet
{
public int Value { get; set; }
@@ -128,6 +152,18 @@ public class WithXmlElement
public int Value { get; set; }
}
+ public class WithXmlAttribute
+ {
+ [XmlAttribute]
+ public int Value { get; set; }
+ }
+
+ public class WithXmlAttributeExplicitName
+ {
+ [XmlAttribute("Name")]
+ public int Value { get; set; }
+ }
+
public class WithXmlIgnore
{
[XmlIgnore]
diff --git a/Gu.Xml/Writers/AttributeWriter.cs b/Gu.Xml/Writers/AttributeWriter.cs
index b4076ea..c56f08e 100644
--- a/Gu.Xml/Writers/AttributeWriter.cs
+++ b/Gu.Xml/Writers/AttributeWriter.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Reflection;
+ using System.Xml.Serialization;
public abstract class AttributeWriter
{
@@ -13,12 +14,20 @@ public AttributeWriter(string name)
public string Name { get; }
- public static AttributeWriter Create(string name, PropertyInfo property)
+ public static bool TryCreate(PropertyInfo property, out AttributeWriter writer)
{
- return (AttributeWriter)typeof(AttributeWriter)
- .GetMethod(nameof(CreateWriter), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod(property.ReflectedType, property.PropertyType)
- .Invoke(null, new object[] { name, property });
+ if (Attribute.GetCustomAttribute(property, typeof(XmlAttributeAttribute)) is XmlAttributeAttribute attribute)
+ {
+ var name = string.IsNullOrEmpty(attribute.AttributeName) ? property.Name : attribute.AttributeName;
+ writer = (AttributeWriter)typeof(AttributeWriter)
+ .GetMethod(nameof(CreateWriter), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod(property.ReflectedType, property.PropertyType)
+ .Invoke(null, new object[] { name, property });
+ return true;
+ }
+
+ writer = null;
+ return false;
}
public abstract void Write(TextWriter writer, T source);
diff --git a/Gu.Xml/Writers/AttributeWriter{TSource,TValue}.cs b/Gu.Xml/Writers/AttributeWriter{TSource,TValue}.cs
index 056b260..4a4a64f 100644
--- a/Gu.Xml/Writers/AttributeWriter{TSource,TValue}.cs
+++ b/Gu.Xml/Writers/AttributeWriter{TSource,TValue}.cs
@@ -21,6 +21,7 @@ public override void Write(TextWriter writer, T source)
{
if (SimpleValueWriter.TryGet(value, out var valueWriter))
{
+ writer.Write(" ");
writer.Write(this.Name);
writer.Write("=\"");
valueWriter.Write(writer, value);
diff --git a/Gu.Xml/Writers/ComplexValueWriter.cs b/Gu.Xml/Writers/ComplexValueWriter.cs
index 0f98fab..e69fa10 100644
--- a/Gu.Xml/Writers/ComplexValueWriter.cs
+++ b/Gu.Xml/Writers/ComplexValueWriter.cs
@@ -31,9 +31,20 @@ public static ComplexValueWriter GetOrCreate(T value)
private static ComplexValueWriter Create(Type type)
{
return new ComplexValueWriter(
- Array.Empty(),
+ Attributes().ToArray(),
Elements().ToArray());
+ IEnumerable Attributes()
+ {
+ foreach (var property in type.GetProperties())
+ {
+ if (AttributeWriter.TryCreate(property, out var writer))
+ {
+ yield return writer;
+ }
+ }
+ }
+
IEnumerable Elements()
{
foreach (var property in type.GetProperties())
diff --git a/Gu.Xml/XmlWriter.cs b/Gu.Xml/XmlWriter.cs
index 09d469d..347535c 100644
--- a/Gu.Xml/XmlWriter.cs
+++ b/Gu.Xml/XmlWriter.cs
@@ -1,6 +1,7 @@
namespace Gu.Xml
{
using System;
+ using System.Collections.Generic;
using System.IO;
///
@@ -40,7 +41,7 @@ public void WriteElement(string name, T value)
}
else if (ComplexValueWriter.GetOrCreate(value) is ComplexValueWriter complex)
{
- this.WriteStartElement(name);
+ this.WriteStartElement(name, value, complex.Attributes);
this.writer.WriteLine();
foreach (var elementWriter in complex.Elements)
{
@@ -69,6 +70,20 @@ public void WriteStartElement(string name)
this.indentLevel++;
}
+ public void WriteStartElement(string name, T source, IReadOnlyList attributeWriters)
+ {
+ this.WriteIndentation();
+ this.writer.Write("<");
+ this.writer.Write(name);
+ foreach (var attributeWriter in attributeWriters)
+ {
+ attributeWriter.Write(this.writer, source);
+ }
+
+ this.writer.Write(">");
+ this.indentLevel++;
+ }
+
public void WriteEndElement(string name)
{
this.writer.Write("");