Skip to content

Commit

Permalink
Support XmlAttributeAttribute #3.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanLarsson committed Sep 9, 2018
1 parent c937897 commit f36fbf4
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 7 deletions.
36 changes: 36 additions & 0 deletions Gu.Xml.Tests/XmlTests.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,30 @@ public void XmlIgnoreAttribute()
Assert.AreEqual(expected, actual);
}

[Test]
public void XmlAttributeAttribute()
{
var with = new WithXmlAttribute { Value = 1 };
var expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine +
"<WithXmlAttribute Value=\"1\">" + Environment.NewLine +
"</WithXmlAttribute>";

var actual = Xml.Serialize(with);
Assert.AreEqual(expected, actual);
}

[Test]
public void XmlAttributeAttributeExplicitName()
{
var with = new WithXmlAttributeExplicitName { Value = 1 };
var expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine +
"<WithXmlAttributeExplicitName Name=\"1\">" + Environment.NewLine +
"</WithXmlAttributeExplicitName>";

var actual = Xml.Serialize(with);
Assert.AreEqual(expected, actual);
}

public class WithGetSet
{
public int Value { get; set; }
Expand Down Expand Up @@ -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]
Expand Down
19 changes: 14 additions & 5 deletions Gu.Xml/Writers/AttributeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;

public abstract class AttributeWriter
{
Expand All @@ -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<T>(TextWriter writer, T source);
Expand Down
1 change: 1 addition & 0 deletions Gu.Xml/Writers/AttributeWriter{TSource,TValue}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public override void Write<T>(TextWriter writer, T source)
{
if (SimpleValueWriter.TryGet(value, out var valueWriter))
{
writer.Write(" ");
writer.Write(this.Name);
writer.Write("=\"");
valueWriter.Write(writer, value);
Expand Down
13 changes: 12 additions & 1 deletion Gu.Xml/Writers/ComplexValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,20 @@ public static ComplexValueWriter GetOrCreate<T>(T value)
private static ComplexValueWriter Create(Type type)
{
return new ComplexValueWriter(
Array.Empty<AttributeWriter>(),
Attributes().ToArray(),
Elements().ToArray());

IEnumerable<AttributeWriter> Attributes()
{
foreach (var property in type.GetProperties())
{
if (AttributeWriter.TryCreate(property, out var writer))
{
yield return writer;
}
}
}

IEnumerable<ElementWriter> Elements()
{
foreach (var property in type.GetProperties())
Expand Down
17 changes: 16 additions & 1 deletion Gu.Xml/XmlWriter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Gu.Xml
{
using System;
using System.Collections.Generic;
using System.IO;

/// <summary>
Expand Down Expand Up @@ -40,7 +41,7 @@ public void WriteElement<T>(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)
{
Expand Down Expand Up @@ -69,6 +70,20 @@ public void WriteStartElement(string name)
this.indentLevel++;
}

public void WriteStartElement<T>(string name, T source, IReadOnlyList<AttributeWriter> 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("</");
Expand Down

0 comments on commit f36fbf4

Please sign in to comment.