2016-08-03 15 views
1

XmlSerializerを使用してシリアル化しているクラスがあります。他のプロパティに加えて、あらかじめ構築されたxmlのチャンクをオブジェクトに追加する必要があります。私はすでにこのポストでxmlのチャックを扱うように頼んだ:How to remove empty namespace attribute on manually added xml string when serializing object?プロパティの属性をシリアル化するか、クラス階層をスキップする方法

これでXML文字列を含むプロパティに属性を追加する必要がある。私はクラスに属性を追加する方法を理解していますが、プロパティには追加しません。属性を保持するための新しいクラスを作成すると、出力に余分な階層ができます。ここで

は私の簡素化コードです:

public class Book 
{ 
    public string Title { get; set; } 

    public string Author { get; set; } 

    public XmlElement Extension { get; set; } 

    public Book() 
    { 
    } 

    public void AddExtension() 
    { 
     string xmlString = "<AdditionalInfo xmlns=\"http://www.somenamespace.com\">" + 
           "<SpecialHandling>Some Value</SpecialHandling>" + 
          "</AdditionalInfo>"; 

     this.Extension = GetElement(xmlString); 
    } 

    public static XmlElement GetElement(string xml) 
    { 
     XmlDocument doc = new XmlDocument(); 

     doc.LoadXml(xml); 

     return doc.DocumentElement; 
    } 
} 

static void Main(string[] args) 
{ 
    TestSerialization p = new TestSerialization(); 

    Book bookOne = new Book(); 

    bookOne.Title = "How to Fix Code"; 
    bookOne.Author = "Dee Bugger"; 

    bookOne.AddExtension(); 

    System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(Book), "http://www.somenamespace.com"); 

    using (var writer = new StreamWriter("C:\\BookReport.xml")) 
    using (var xmlWriter = XmlWriter.Create(writer, new XmlWriterSettings { Indent = true })) 
    { 
     serializer.Serialize(xmlWriter, bookOne); 
    } 
} 

それは次のような出力を生成します。

<?xml version="1.0" encoding="utf-8"?> 
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.somenamespace.com"> 
    <Title>How to Fix Code</Title> 
    <Author>Dee Bugger</Author> 
    <Extension> 
    <AdditionalInfo xmlns="http://www.somenamespace.com"> 
     <SpecialHandling>Some Value</SpecialHandling> 
    </AdditionalInfo> 
    </Extension> 
</Book> 

今、私のような拡張出力に見えるように拡張に属性を追加する必要があります。

... 
<Extension Modifier="ABC"> 
    <AdditionalInfo xmlns="http://www.somenamespace.com"> 
     <SpecialHandling>Some Value</SpecialHandling> 
    </AdditionalInfo> 
</Extension> 

Bookクラスを変更する方法はありますか?私は、XML文字列の修飾属性とのXmlElementを保持するための拡張クラスを作成しようとしましたが、それは余分なレベルの結果:

public class Extension 
{ 
    [XmlAttribute] 
    public string Modifier { get; set; } 

    [XmlElementAttribute("Extension")] 
    public XmlElement ExtensionAsElement { get; set; } 

    public Extension() 
    { 
    } 

    public Extension(XmlElement extensionAsElement) 
    { 
     this.Modifier = "ABC"; 

     this.ExtensionAsElement = extensionAsElement; 
    } 
} 

public class Book 
{ 
    public string Title { get; set; } 

    public string Author { get; set; } 

    [XmlElementAttribute("Extension")] 
    public Extension ExtensionObj { get; set; } 

    public Book() 
    { 
    } 

    public void AddExtension() 
    { 
     string xmlString = "<AdditionalInfo xmlns=\"http://www.somenamespace.com\">" + 
           "<SpecialHandling>Some Value</SpecialHandling>" + 
          "</AdditionalInfo>"; 

     this.ExtensionObj = new Extension(GetElement(xmlString)); 
    } 

    public static XmlElement GetElement(string xml) 
    { 
     XmlDocument doc = new XmlDocument(); 

     doc.LoadXml(xml); 

     return doc.DocumentElement; 
    } 
} 

<?xml version="1.0" encoding="utf-8"?> 
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.somenamespace.com"> 
    <Title>How to Fix Code</Title> 
    <Author>Dee Bugger</Author> 
    <Extension Modifier="ABC"> 
    <Extension> 
     <AdditionalInfo xmlns="http://www.somenamespace.com"> 
     <SpecialHandling>Some Value</SpecialHandling> 
     </AdditionalInfo> 
    </Extension> 
    </Extension> 
</Book> 

注:これは私のコードの過度に単純化した例であり、Bookクラスがあります私のルートではありません。私はシリアライズするだけで、デシリアライズする必要はありません。

答えて

0

あなたは要素<Extension>自体としてではなく、その名前の要素のとしてXMLストリームにそのままお使いExtensionプロパティが挿入されるべきことを指定する[XmlAnyElement("Extension")]を使用することができます。これを実行すると、SetAttribute()GetAttribute()を使用して要素自体に属性を設定できます。

public class Book 
{ 
    public string Title { get; set; } 

    public string Author { get; set; } 

    [XmlAnyElement("Extension")] 
    public XmlElement Extension { get; set; } 

    public Book() 
    { 
     this.Extension = new XmlDocument().CreateElement("Extension"); 
    } 

    public Book AddExtension() 
    { 
     string innerXmlString = "<AdditionalInfo xmlns=\"http://www.somenamespace.com\">" + 
           "<SpecialHandling>Some Value</SpecialHandling>" + 
          "</AdditionalInfo>"; 
     if (Extension == null) 
      // Since Extension is marked with [XmlAnyElement("Extension")], its value must 
      // be an XmlElement named "Extension". Its InnerXml can be anything. 
      Extension = new XmlDocument().CreateElement("Extension"); 
     Extension.InnerXml = innerXmlString; 
     return this; 
    } 

    const string ModifierName = "Modifier"; 

    [XmlIgnore] 
    public string Modifier 
    { 
     get 
     { 
      if (Extension == null) 
       return null; 
      return Extension.GetAttribute(ModifierName); 
     } 
     set 
     { 
      if (Extension == null) 
       AddExtension(); 
      if (value == null) 
       Extension.RemoveAttribute(ModifierName); 
      else 
       Extension.SetAttribute(ModifierName, value); 
     } 
    } 
} 

そして次からXMLを作成:

このように、あなたのBookクラスのようなものになり

var bookOne = new Book { Title = "How to Fix Code", Author = "Dee Bugger", Modifier = "AAA" } 
    .AddExtension(); 

は、結果を生成します:

<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Title>How to Fix Code</Title> 
    <Author>Dee Bugger</Author> 
    <Extension Modifier="AAA"> 
     <AdditionalInfo xmlns="http://www.somenamespace.com"> 
      <SpecialHandling>Some Value</SpecialHandling> 
     </AdditionalInfo> 
    </Extension> 
</Book> 
+0

ありがとうございました@ dbc。私はXmlAnyElementが異なるタイプの配列に使われているのを見ただけでした。これは非常に役に立ち、私の問題を解決しました! – sldorman

+0

申し訳ありませんが、私は考えていました:) – sldorman

関連する問題