2009-08-17 12 views
1

J'essaye d'implémenter quelques fonctions qui convertiront un objet en un autre avec XslCompiledTransform.XslCompiledTransform et Sérialisation

J'ai trouvé quelques implémentations pour sérialiser un objet en chaîne XML et désérialiser la chaîne XML vers un objet.

Une autre fonction fait XslCompiledTransform de object1 à obejbct2.

Pour générer le fichier XSLT j'ai utilisé l'Altova MapForce, juste chargé le XML des objets sérialisés et mappé certains attributs.

Maintenant, pour les problèmes:

  • premier je remarquai que la XslCompiledTransform ne fonctionne pas avec la version 2.0 XSLT. Y at-il des fonctions plus récentes qui fonctionnent avec XSLT 2.0? peut-être quelques paramètres?
  • d'autre part, je reçois une exception lors de la tentative de désérialiser le XML à un objet: "Il y avait une erreur de désérialisation de l'objet de type myObject La chaîne d'entrée n'était pas dans un format correct." Je ne comprends pas où est le problème. Est-ce que quelqu'un a un exemple de code qui fait une telle chose? tout ce que je trouve dans google sont des transformations de code HTML et non des objets.

Voici les fonctions:

private static string runXSLT(string xsltFile, string inputXML) 
     { 
      XmlDocument XmlDoc = new XmlDocument(); 

      // Load the style sheet. 
      XslCompiledTransform xslt = new XslCompiledTransform(true); 
      xslt.Load(xsltFile); 

      StringReader StrReader = new StringReader(inputXML); 
      XmlTextReader XmlReader = new XmlTextReader(StrReader); 


      //Create an XmlTextWriter which outputs to memory stream 
      Stream stream = new MemoryStream(); 
      XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8); 

      // Execute the transform and output the results to a file. 
      xslt.Transform(XmlReader, writer); 

      stream.Position = 0; 
      XmlDoc.Load(stream); 
      return XmlDoc.InnerXml; 
     } 

public static string SerializeAnObject(object AnObject) 
     { 
      XmlDocument XmlDoc = new XmlDocument(); 
      DataContractSerializer xmlDataContractSerializer = new DataContractSerializer(AnObject.GetType()); 
      MemoryStream MemStream = new MemoryStream(); 
      try 
      { 
       xmlDataContractSerializer.WriteObject(MemStream, AnObject); 
       MemStream.Position = 0; 
       XmlDoc.Load(MemStream); 
       return XmlDoc.InnerXml; 
      } 
      finally 
      { 
       MemStream.Close(); 
      } 

     } 

    public static Object DeSerializeAnObject(string XmlOfAnObject, Type ObjectType) 
    { 
     StringReader StrReader = new StringReader(XmlOfAnObject); 
     DataContractSerializer xmlDataContractSerializer = new DataContractSerializer(ObjectType); 
     XmlTextReader XmlReader = new XmlTextReader(StrReader); 
     try 
     { 
      Object AnObject = xmlDataContractSerializer.ReadObject(XmlReader); 
      return AnObject; 
     } 
     finally 
     { 
      XmlReader.Close(); 
      StrReader.Close(); 
     } 
    } 

Merci assignent,

Omri.

Répondre

3
  • XslCompiledTransform ne prend pas en charge XSLT 2.0. En fait, XSLT 2.0 n'est pas du tout supporté par .NET Framework (vous pouvez essayer la version Saxon pour .NET, mais sachez qu'il s'agit simplement de la version Java exécutée dans IKVM).

  • De votre description, je n'ai pas compris pourquoi vous prenez le détour via XML pour convertir un objet en un autre. Pourquoi ne fournissez-vous pas simplement un constructeur dans votre objet cible qui prend votre objet d'entrée comme paramètre? Ensuite, vous pouvez coder tout le mappage à l'intérieur de ce constructeur. Ce n'est pas seulement beaucoup plus efficace que de sérialiser, transformer et désérialiser vos objets, vous obtiendrez également le type de sécurité de C#.

+1

+1 pour l'utilisation d'un constructeur pour convertir la classe d'origine à la nouvelle classe –

+0

Le but d'utiliser la transformation XSL est de faire le mappage d'un objet à un autre, donc je ne codé en dur peut modifier les propriétés mappées sans compiler le projet. En fait, je construis ceci pour mapper les données entre les services Web. Je reçois les données A de WS 1 et les données B de WS 2, maintenant je dois construire une nouvelle classe à soumettre à WS 3. La classe de réponse est construite à partir de l'objet A + B. Maintenant si WS 1 reviendra dans le futur un objet différent A (A.name changé en A.firstName) Je peux changer le mapping dans le fichier XSLT et le faire sans recompiler le projet. Merci pour la réponse rapide! –