2009-04-06 10 views
2

私は、変更したくないXMLファイルがある状況があります。 XElementクラスのAddAnnotation関数は、直列化されておらずXMLの一部ではないメモリのみのデータを追加するオプションを提供します。XMLシリアライズ

これらの注釈を(別のXMLファイルなどに)保存してから、同じオブジェクトを取得するためにxmlと注釈の両方をデシリアライズする必要があります。

元のxmlを変更したくないので、それが注釈を使用する理由です。

要約すると、カスタムデータをxmlファイルに追加できます。このデータは、シリアル化するときにXMLの一部ではなく、XMLの一部になりますが、元のXMLを簡単に取得できます。

このようなことをどのように行うことができますか?

編集: xml処理命令を使用する必要がありますか?この種の使用を目的とした処理指示はありますか?

答えて

2

それが最も簡単な方法は、通常のノードを使用することであろうように私に聞こえるが、異なるXML名前空間に - すなわち

<foo standardAttrubute="abc" myData:customAttribute="def"> 
    <standardElement>ghi</standardElement > 
    <myData:customElement>jkl</myData:customElement> 
</foo> 

myDataは、名前空間URIのxmlnsエイリアスです)

多くの場合、読者は名前空間(またはデフォルト/空の名前空間)のデータのみをチェックしています。カスタム名前空間の値は一般的にスキップされます。

元のXMLをパックするには、デフォルト/元の名前空間のみを尊重するxsltを使用して簡単な方法で実行します。


XNamespace myData = XNamespace.Get("http://mycustomdata/"); 
XElement el = new XElement("foo", 
    new XAttribute(XNamespace.Xmlns + "myData", myData.NamespaceName), 
    new XAttribute("standardAttribute", "abc"), 
    new XAttribute(myData + "customAttribute", "def"), 
    new XElement("standardElement", "ghi"), 
    new XElement(myData + "customAttribute", "jkl")); 
string s = el.ToString(); 

おそらく、XElementからそのようなデータを削除する:

+0

サウンドを面白い...あなたは例を提供できますか(実際には2つの例) XElementを使用してxmlを読み込むことができます。 –

+0

作成が追加されました - それはあなたが意味するものですか?または、他の何か? –

+0

いいえ、私はXMLを作成する方法を知っています。私はどのように私はそれをカスタムデータなしで読み込むのか分からない。 tnx! –

1
static void Strip(XElement el, XNamespace ns) { 
     List<XElement> remove = new List<XElement>(); 
     foreach (XElement child in el.Elements()) { 
      if (child.Name.Namespace == ns) { 
       remove.Add(child); 
      } else { 
       Strip(child, ns); 
      } 
     } 
     remove.ForEach(child => child.Remove()); 

     foreach (XAttribute child in 
      (from a in el.Attributes() 
      where a.Name.Namespace == ns 
      select a).ToList()) { 
      child.Remove(); 
     } 
    } 

を元の質問は、単語 "シリアル化" を使用するが、その後ものXElementと注釈を挙げます。私にとっては、これらは2つの異なるものです。

あなたが本当にXmlSerializerを使用する場合:私はどうなるのか
は、シリアライズを区別するために、使用XmlAttributeOverridesです。 XmlAttributeOverridesを使用すると、実行時にプログラムで、型を修飾するxmlシリアル化属性をオーバーライドできます。

注釈/ドキュメントを保持するフィールド/プロパティをタイプすることができます。 XmlIgnoreでそれを飾る。次に、オーバーライドを受け入れないXmlSerializerのインスタンスを1つ作成します。注釈はシリアライズされたりデシリアライズされたりしません。 XmlAttributeOverridesオブジェクトを使用して、その型のXmlSerializerの別のインスタンスを作成します。 XmlIgnoreのプロパティ(XmlElementAttributeを使用)のオーバーライドと、他のメンバーの任意の属性のオーバーライドを指定します(XmlIgnore = trueを使用)。

各シリアライザでインスタンスを2回シリアル化します。


編集:ここではコードです:

public class DTO 
{ 
    [XmlIgnore] 
    public string additionalInformation; 

    [XmlElement(Order=1)] 
    public DateTime stamp; 

    [XmlElement(Order=2)] 
    public string name; 

    [XmlElement(Order=3)] 
    public double value; 

    [XmlElement(Order=4)] 
    public int index; 
} 



public class OverridesDemo 
{ 
    public void Run() 
    { 
     DTO dto = new DTO 
      { 
       additionalInformation = "This will bbe serialized separately", 
       stamp = DateTime.UtcNow, 
       name = "Marley", 
       value = 72.34, 
       index = 7 
      }; 


     // --------------------------------------------------------------- 
     // 1. serialize normally 
     // this will allow us to omit the xmlns:xsi namespace 
     var ns = new XmlSerializerNamespaces(); 
     ns.Add("", ""); 

     XmlSerializer s1 = new XmlSerializer(typeof(DTO)); 

     var builder = new System.Text.StringBuilder(); 
     var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent= true }; 

     Console.WriteLine("\nSerialize using the in-line attributes: "); 
     using (XmlWriter writer = XmlWriter.Create(builder, settings)) 
     { 
      s1.Serialize(writer, dto, ns); 
     } 
     Console.WriteLine("{0}",builder.ToString()); 
     Console.WriteLine("\n");    
     // --------------------------------------------------------------- 

     // --------------------------------------------------------------- 
     // 2. serialize with attribute overrides 
     // use a non-empty default namespace 
     ns = new XmlSerializerNamespaces(); 
     string myns = "urn:www.example.org"; 
     ns.Add("", myns); 

     XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

     XmlAttributes attrs = new XmlAttributes(); 
     // override the (implicit) XmlRoot attribute 
     XmlRootAttribute attr1 = new XmlRootAttribute 
      { 
       Namespace = myns, 
       ElementName = "DTO-Annotations", 
      }; 
     attrs.XmlRoot = attr1; 

     overrides.Add(typeof(DTO), attrs); 
     // "un-ignore" the first property 
     // define an XmlElement attribute, for a type of "String", with no namespace 
     var a2 = new XmlElementAttribute(typeof(String)) { ElementName="note", Namespace = myns }; 

     // add that XmlElement attribute to the 2nd bunch of attributes 
     attrs = new XmlAttributes(); 
     attrs.XmlElements.Add(a2); 
     attrs.XmlIgnore = false; 

     // add that bunch of attributes to the container for the type, and 
     // specifically apply that bunch to the "additionalInformation" property 
     // on the type. 
     overrides.Add(typeof(DTO), "additionalInformation", attrs); 

     // now, XmlIgnore all the other properties 
     attrs = new XmlAttributes(); 
     attrs.XmlIgnore = true;  
     overrides.Add(typeof(DTO), "stamp", attrs); 
     overrides.Add(typeof(DTO), "name", attrs); 
     overrides.Add(typeof(DTO), "value", attrs); 
     overrides.Add(typeof(DTO), "index", attrs); 

     // create a serializer using those xml attribute overrides 
     XmlSerializer s2 = new XmlSerializer(typeof(DTO), overrides); 

     Console.WriteLine("\nSerialize using the override attributes: "); 
     builder.Length = 0; 
     using (XmlWriter writer = XmlWriter.Create(builder, settings)) 
     { 
      s2.Serialize(writer, dto, ns); 
     } 
     Console.WriteLine("{0}",builder.ToString()); 
     Console.WriteLine("\n");    
     // --------------------------------------------------------------- 
    } 
} 

出力が使用して、インライン属性:

<DTO> 
    <stamp>2009-06-30T02:17:35.918Z</stamp> 
    <name>Marley</name> 
    <value>72.34</value> 
    <index>7</index> 
</DTO> 

出力は、オーバーライドを使用して属性:

<DTO-Annotations xmlns="urn:www.example.org"> 
    <note>This will bbe serialized separately</note> 
</DTO-Annotations> 
+0

私はそれに従ったかどうか分からない。スニペットを提供できますか? tnx ... –

関連する問題