2009-07-29 10:03:20 -07:00
|
|
|
|
/*
|
|
|
|
|
* 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;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Xml;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace Boare.Lib.AppUtil {
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// フィールド、またはプロパティの概要を格納するattribute
|
|
|
|
|
/// </summary>
|
|
|
|
|
[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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// フィールドおよびプロパティを、XmlItemDescription属性の文字列を付加しながらXmlシリアライズする
|
|
|
|
|
/// </summary>
|
|
|
|
|
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<int> f = new List<int>();
|
|
|
|
|
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 ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|