2012-04-26 7 views
2

XMLからクラスを簡単に構築する方法はありますか?構築されたクラスは、XMLのシリアライズとデシリアライズに使用されます。シリアル化のためのXMLクラスジェネレータ

私は多くのプロパティと要素が定義されたXMLを持っています。そのXMLに基づいて自分のクラスを手動で作成する必要がありますか?または方法についてラウンドXMLから

おかげで、

Esen

+0

どの言語ですか? –

+0

あなたのクラスを構築するために使用している言語/プラットフォームは何ですか? – pmartin

+0

ご迷惑をおかけして申し訳ありません。私はMicrosoft.NET(VB.NETまたはC#.NET)を探しています – Esen

答えて

1

@Willem van Rumpt:解決策は、クラスを生成するのに役立ちました。しかし、データセットをインスタンス化しようとすると、「同じテーブルを2つのネストされたリレーションの子テーブルにすることはできません」という例外が発生することがあります。

xmldocumentオブジェクトを使用して各ノードxmlファイルをシリアライズしてデシリアライズするために使用できるクラスを生成します。似たような解決策を探している人に役立つように、ここに投稿することを考えました。最適化されたソリューションがあれば投稿してください。

namespace Utility1 
{ 
public static class XMLHelper 
{ 
    private enum XMLType 
    { 
     Element, 
     Attribute 
    } 
    public static string GenerateXMLClass(string xmlstring) 
    { 
     XmlDocument xd = new XmlDocument(); 
     xd.LoadXml(xmlstring); 
     XmlNode rootNode = xd.DocumentElement; 
     var xmlClassCollection = new Dictionary<string, XMLClass>(); 
     var xmlClass = new XMLClass(); 
     xmlClassCollection.Add(rootNode.Name, xmlClass); 
     CollectAttributes(ref xmlClass, rootNode); 
     CollectElements(ref xmlClass, rootNode); 
     CollectChildClass(ref xmlClassCollection, rootNode); 

     var clsBuilder = new StringBuilder(); 

     clsBuilder.AppendLine("[XmlRoot(\"" + rootNode.Name + "\")]"); 

     foreach (var cls in xmlClassCollection) 
     { 
      clsBuilder.AppendLine("public class " + cls.Key); 
      clsBuilder.AppendLine("{"); 

      foreach (var element in cls.Value.Elements) 
      { 
       if (XMLType.Element == element.XmlType) 
        clsBuilder.AppendLine("[XmlElement(\"" + element.Name + "\")]"); 
       else 
        clsBuilder.AppendLine("[XmlAttribute(\"" + element.Name + "\")]"); 
       clsBuilder.AppendLine("public " + element.Type + element.Name + "{get;set;}"); 
      } 

      clsBuilder.AppendLine("}"); 
     } 

     return clsBuilder.ToString(); 
    } 

    private static void CollectAttributes(ref XMLClass xmlClass, XmlNode node) 
    { 
     if (null != node.Attributes) 
     { 
      foreach (XmlAttribute attr in node.Attributes) 
      { 
       if (null == xmlClass.Elements.SingleOrDefault(o => o.Name == attr.Name)) 
        xmlClass.Elements.Add(new Element("string ", attr.Name, XMLType.Attribute)); 
      } 
     } 
    } 

    private static bool IsEndElement(XmlNode node) 
    { 
     if ((null == node.Attributes || node.Attributes.Count <= 0) && 
        (null == node.ChildNodes || !node.HasChildNodes || (node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text))) 
     { 
      return true; 
     } 
     return false; 
    } 

    private static void CollectElements(ref XMLClass xmlClass, XmlNode node) 
    { 
     foreach (XmlNode childNode in node.ChildNodes) 
     { 
      if (null == xmlClass.Elements.SingleOrDefault(o => o.Name == childNode.Name)) 
      { 
       var occurance = node.ChildNodes.Cast<XmlNode>().Where(o => o.Name == childNode.Name).Count(); 
       var appender = " "; 
       if (occurance > 1) 
        appender = "[] "; 

       if(IsEndElement(childNode)) 
       { 
        xmlClass.Elements.Add(new Element("string" + appender, childNode.Name, XMLType.Element)); 
       } 
       else 
       { 
        xmlClass.Elements.Add(new Element(childNode.Name + appender, childNode.Name, XMLType.Element)); 
       } 
      } 
     } 
    } 

    private static void CollectChildClass(ref Dictionary<string, XMLClass> xmlClsCollection, XmlNode node) 
    { 
     foreach (XmlNode childNode in node.ChildNodes) 
     { 
      if (!IsEndElement(childNode)) 
      { 
       XMLClass xmlClass; 
       if (xmlClsCollection.ContainsKey(childNode.Name)) 
        xmlClass = xmlClsCollection[childNode.Name]; 
       else 
       { 
        xmlClass = new XMLClass(); 
        xmlClsCollection.Add(childNode.Name, xmlClass); 
       } 
       CollectAttributes(ref xmlClass, childNode); 
       CollectElements(ref xmlClass, childNode); 
       CollectChildClass(ref xmlClsCollection, childNode); 
      } 
     } 
    } 

    private class XMLClass 
    { 
     public XMLClass() 
     { 
      Elements = new List<Element>(); 
     } 
     public List<Element> Elements { get; set; } 
    } 

    private class Element 
    { 
     public Element(string type, string name, XMLType xmltype) 
     { 
      Type = type; 
      Name = name; 
      XmlType = xmltype; 
     } 
     public XMLType XmlType { get; set; } 
     public string Name { get; set; } 
     public string Type { get; set; } 
    } 
    } 
} 

ウィレムのポストにさらに感謝、

Esen

+0

ところで、これは文字列プロパティを持つクラスを作成します。値を検証し、適切なプロパティタイプを割り当てる必要があります。 – Esen

+0

私は個人的にこの問題に対するロール・ツー・オーナー自身の解決策を避けたいと言わざるを得ない(多くの(たくさんの落とし穴がある))。それはあなたのために働く場合:素晴らしい:) –

2

をクラスを生成するために利用できるユーティリティツールがあるがありますされています:xsd.exeを使用して は、あなたが最初にあなたのXMLファイルからスキーマ(XSD)を作成することができますこれをxsd.exeの入力として使用して、スキーマからクラスを生成することができます。 即ち(コマンドプロンプトから):

xsd.exe myXmlFile.xml 

出力myXmlFile.xsd

と次

xsd.exe myXmlFile.xsd 

にXSDファイルからクラスを生成します。

+0

これは私が探しているものをまっすぐ前方の結果を提供しません。しかし、このヒントは役に立ちます。私はそこから私が探しているクラスを生成することができますデータセットを生成することができます。助けてくれてありがとうRumpt。 – Esen

3

これはこれは、C#クラスを生成し、XSD(ないデータセット

xsd.exe myCustom.xml 

を生成します。 :

xsd.exe myCustom.xsd /c 
+0

生成されたC#クラスは何ですか?それはデータセットではありませんか?私はあなたにcode4lifeを与えなかった – Esen