/* * XmlSerializeWithDescription.cs * Copyright (c) 2009 kbinani * * This file is part of Boare.Lib.AppUtil. * * Boare.Lib.AppUtil is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * Boare.Lib.AppUtil is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Reflection; using System.IO; namespace Boare.Lib.AppUtil { /// /// フィールド、またはプロパティの概要を格納するattribute /// [AttributeUsage( AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false )] public class XmlItemDescription : Attribute { private string m_value = ""; private string m_attribute_name = "description"; public XmlItemDescription( string Value ) { m_value = Value; } public XmlItemDescription( string AttributeName, string Value ) { m_value = Value; m_attribute_name = AttributeName; } public string AttributeName { get { return m_attribute_name; } } public string Value { get { return m_value; } } } /// /// フィールドおよびプロパティを、XmlItemDescription属性の文字列を付加しながらXmlシリアライズする /// public class XmlSerializeWithDescription { private XmlTextWriter m_writer; private Type m_type; public XmlSerializeWithDescription() { } public void Serialize( Stream stream, object obj ) { m_writer = new XmlTextWriter( stream, null ); m_writer.Formatting = Formatting.Indented; m_writer.Indentation = 4; m_writer.IndentChar = ' '; m_writer.WriteStartDocument(); m_writer.WriteStartElement( obj.GetType().Name ); PrintItemRecurse( obj ); m_writer.WriteEndElement(); m_writer.WriteEndDocument(); m_writer.Flush(); } private void PrintItemRecurse( object obj ) { Type t = obj.GetType(); if ( !TryWriteValueType( obj ) ){ if ( t.IsGenericType ) { List f = new List(); Type list_type = f.GetType().GetGenericTypeDefinition(); if ( t.GetGenericTypeDefinition().Equals( list_type ) ) { Type[] gen = t.GetGenericArguments(); if ( gen.Length == 1 ) { PropertyInfo count_property = t.GetProperty( "Count", typeof( int ) ); int count = (int)count_property.GetValue( obj, new object[] { } ); Type returntype = gen[0]; MethodInfo indexer = t.GetMethod( "get_Item", new Type[] { typeof( int ) } ); string name = ""; if ( returntype.Equals( typeof( Boolean ) ) ) { name = "boolean"; } else if ( returntype.Equals( typeof( DateTime ) ) ) { name = "dateTime"; } else if ( returntype.Equals( typeof( Decimal ) ) ) { name = "decimal"; } else if ( returntype.Equals( typeof( Double ) ) ) { name = "double"; } else if ( returntype.Equals( typeof( Int32 ) ) ) { name = "int"; } else if ( returntype.Equals( typeof( Int64 ) ) ) { name = "long"; } else if ( returntype.Equals( typeof( Single ) ) ) { name = "float"; } else if ( returntype.Equals( typeof( String ) ) ) { name = "string"; } else if ( returntype.IsEnum ) { name = returntype.Name; } if ( indexer != null && name != "" ) { for ( int i = 0; i < count; i++ ) { object value = indexer.Invoke( obj, new object[] { i } ); m_writer.WriteStartElement( name ); TryWriteValueType( value ); m_writer.WriteEndElement(); } } } } } else { foreach ( FieldInfo fi in t.GetFields() ) { if ( fi.IsPrivate || fi.IsStatic ) { continue; } object[] attr = fi.GetCustomAttributes( typeof( XmlItemDescription ), false ); XmlItemDescription xid = null; if ( attr.Length > 0 ) { xid = (XmlItemDescription)attr[0]; } WriteContents( fi.Name, fi.GetValue( obj ), xid ); } foreach ( PropertyInfo pi in t.GetProperties() ) { if ( !pi.CanRead | !pi.CanWrite ) { continue; } if ( !pi.GetSetMethod().IsPublic | !pi.GetGetMethod().IsPublic ) { continue; } if ( pi.GetSetMethod().IsStatic | pi.GetGetMethod().IsStatic ) { continue; } object[] attr = pi.GetCustomAttributes( typeof( XmlItemDescription ), false ); XmlItemDescription xid = null; if ( attr.Length > 0 ) { xid = (XmlItemDescription)attr[0]; } WriteContents( pi.Name, pi.GetValue( obj, new object[] { } ), xid ); } } } } private bool TryWriteValueType( object obj ) { Type t = obj.GetType(); if ( t.Equals( typeof( Boolean ) ) ) { m_writer.WriteValue( (Boolean)obj ); return true; } else if ( t.Equals( typeof( DateTime ) ) ) { m_writer.WriteValue( (DateTime)obj ); return true; } else if ( t.Equals( typeof( Decimal ) ) ) { m_writer.WriteValue( (Decimal)obj ); return true; } else if ( t.Equals( typeof( Double ) ) ) { m_writer.WriteValue( (Double)obj ); return true; } else if ( t.Equals( typeof( Int32 ) ) ) { m_writer.WriteValue( (Int32)obj ); return true; } else if ( t.Equals( typeof( Int64 ) ) ) { m_writer.WriteValue( (Int64)obj ); return true; } else if ( t.Equals( typeof( Single ) ) ) { m_writer.WriteValue( (Single)obj ); return true; } else if ( t.Equals( typeof( String ) ) ) { m_writer.WriteString( (String)obj ); return true; } else if ( t.IsEnum ) { string val = Enum.GetName( t, obj ); m_writer.WriteString( val ); return true; } else { return false; } } private void WriteContents( string name, object next_obj, XmlItemDescription xid ) { m_writer.WriteStartElement( name ); if ( xid != null ) { m_writer.WriteAttributeString( xid.AttributeName, xid.Value ); } PrintItemRecurse( next_obj ); m_writer.WriteEndElement(); } private void test() { System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer( typeof( int ) ); } } }