Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9541

C#でXMLをシリアライズ出力するためのハックいろいろ

$
0
0

指定された形式でXMLを出力しようとした時に毎回検索してはあっちこっちから情報拾ってる気がするのでまとめていく。
ちまちま増やしていくつもりです。

・環境
・C#7.0~8.0
・.Net Framework 4.7
・.Net Core 3.1

Nullable<T>=nullの項目のタグを出力しない

こんな場合。

モデル
[XmlRoot]publicclassLibrary{[XmlElement]publicUser[]Users{get;set;}}publicclassUser{[XmlElement]publicint?Age{get;set;}[XmlElement]publicstringName{get;set;}}
出力
<?xml version="1.0" encoding="utf-8"?><Libraryxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Users><Agexsi:nil="true"/><!--これを出力したくない--><Name>user1</Name></Users></Library>

bool型で制御したいプロパティ名+Specifiedのプロパティを定義することでタグの出力/非出力を制御できるのでそれを利用します。

コード
[XmlRoot]publicclassLibrary{[XmlElement]publicUser[]Users{get;set;}}publicclassUser{[XmlElement]publicint?Age{get;set;}// Age == null の場合falseが返ってタグが出力されなくなる// 完全にシリアライズ制御用のプロパティなのでBrowsable=falseにしてインテリセンスで表示されないようにもしています[XmlIgnore,Browsable(false)]publicboolAgeSpecified=>Age.HasValue;[XmlElement]publicstringName{get;set;}}
出力
<?xml version="1.0" encoding="utf-8"?><Libraryxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Users><Name>user1</Name></Users></Library>

構造体のシリアライズ

変換処理を書くだけといえばそれだけ

[XmlRoot]publicclassLibrary{[XmlIgnore]publicColorSomeColor{get;set;}[XmlElement("FontColor"),Browsable(false)]publicstringSomeColorValue{get{return$"#{SomeColor.A}{SomeColor.R}{SomeColor.G}{SomeColor.B}";}set{SomeColor=ColorTranslator.FromHtml(value);}}}
出力
<?xml version="1.0" encoding="utf-8"?><Libraryxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"><FontColor>#12345678</FontColor></Library>

DateTimeのフォーマットなんかもこれでやらざるをえない気がする。

xmlnsを外す

ちょっと古いアプリとの連携とかで要求されがちな気がする。
xmlをプレーンテキストとして処理する場合とかにも

コード
classProgram{staticvoidMain(string[]args){varapp=newLibrary(){Names=newstring[]{}}using(varwriter=newStreamWriter("application.xml")){// 空白のnamespaceを用意するvarns=newXmlSerializerNamespaces();ns.Add(string.Empty,string.Empty);varserializer=newXmlSerializer(typeof(Library));serializer.Serialize(writer,app,ns);// 空白のnamespaceを使ってシリアライズ}}}[XmlRoot]publicclassLibrary{publicstring[]Names{get;set;}}
出力
<?xml version="1.0" encoding="utf-8"?><Library><Names/></Library>

後書き

なんかもっといい方法あったら教えてほしいなって。


Viewing all articles
Browse latest Browse all 9541

Trending Articles