locked
Save data from textreader to new XML file. RRS feed

  • Question

  • User-865231019 posted

    Hi, 

    I've been working on this for weeks now and I just can't get my head around it and I hope someone can help. 

    I've imported an XML file in to a textreader like so:

     protected void btnSerialization_Click(object sender, EventArgs e)
            {
                // This reads the XML file and puts all the data in to the OrcharblogData object.
                XmlRootAttribute xRoot = new XmlRootAttribute();
                xRoot.ElementName = "Data";
                xRoot.IsNullable = true;
    
                XmlSerializer deserializer = new XmlSerializer(typeof(Data), xRoot);
                TextReader textReader = new StreamReader(Server.MapPath("export.xml"));
    
                Data OrchardblogData = new Data();
                OrchardblogData = (Data)deserializer.Deserialize(textReader);
    
                textReader.Close();
    
    
    
            }

    and when I hover over  'OrchardblogData' I can see all of the data correctly imported from the XML file. So that is the first step working, importing the data and it wasn't very hard to do, but this is where I get stuck.

    I've created class and xsd files from a sample target XML file using the xsd.exe tool which gives me the new schema that I need to convert the data in to. Basically converting my blog export in to BlogML format.

    The issue I am having is where do I go now. 

    I need to convert my XML which has been imported, in to the following XML style, which as I said, I've created a class file from it.  https://raw.githubusercontent.com/wiki/Shazwazza/Articulate/BlogMLSample1.xml

    I guess I'm going to need to create a foreach loop that will go through each blogpost node and built up the elements, saving the relevant data from my source to the new elements on the target?

    This is a sample of my imported XML file (source): 

        <BlogPost Id="/alias=The Blog\/2012\/09\/10\/on-starters-orders" Status="Published">
          <TextField.Excerpt />
          <TaxonomyField.Categories Terms="" />
          <TaxonomyField.Tags Terms="" />
          <BodyPart Text="The main body of my blog" />
          <CommonPart Owner="/User.UserName=Owain" Container="/alias=blog" CreatedUtc="2012-09-10T13:27:00Z" PublishedUtc="2012-09-25T08:57:25Z" ModifiedUtc="2012-09-25T08:56:15Z" />
          <AutoroutePart Alias="The Blog/2012/09/10/on-starters-orders" UseCustomPattern="false" />
          <TitlePart Title="On starters orders....." />
          <CommentsPart CommentsShown="true" CommentsActive="true" ThreadedComments="false" />
          <TagsPart Tags="" />
        </BlogPost>
        <BlogPost Id="/alias=The Blog\/2012\/09\/09\/first-race-on-a-track" Status="Published">
          <TextField.Excerpt />
          <TaxonomyField.Categories Terms="" />
          <TaxonomyField.Tags Terms="" />
          <BodyPart Text="The main body of the second blog post" />
          <CommonPart Owner="/User.UserName=Owain" Container="/alias=blog" CreatedUtc="2012-09-09T13:00:00Z" PublishedUtc="2012-09-25T08:56:53Z" ModifiedUtc="2012-09-25T08:56:53Z" />
          <AutoroutePart Alias="The Blog/2012/09/09/first-race-on-a-track" UseCustomPattern="false" />
          <TitlePart Title="First race on a track" />
          <CommentsPart CommentsShown="true" CommentsActive="true" ThreadedComments="false" />
          <TagsPart Tags="" />
        </BlogPost>
        <BlogPost Id="/alias=The Blog\/2012\/09\/11\/great-night-for-a-run" Status="Published">
          <TextField.Excerpt />
          <TaxonomyField.Categories Terms="" />
          <TaxonomyField.Tags Terms="" />
          <BodyPart Text="The main body of the third blog post" />
          <CommonPart Owner="/User.UserName=Owain" Container="/alias=blog" CreatedUtc="2012-09-11T19:00:00Z" PublishedUtc="2012-10-07T20:44:39Z" ModifiedUtc="2012-10-07T20:44:39Z" />
          <AutoroutePart Alias="The Blog/2012/09/11/great-night-for-a-run" UseCustomPattern="false" />
          <TitlePart Title="Great night for a run!" />
          <CommentsPart CommentsShown="true" CommentsActive="true" ThreadedComments="false" />
          <TagsPart Tags="training" />
        </BlogPost>

    I've got this project in TFS online and I'm happy to share it with anyone if they can help me. 

    I've been told I could look at XSLT conversion but I would like to crack it with this method as I'd like to learn about Serialization and Deserialization. Thanks. 

    Wednesday, May 6, 2015 8:58 AM

All replies

  • User1711366110 posted

    I guess I'm going to need to create a foreach loop that will go through each blogpost node and built up the elements, saving the relevant data from my source to the new elements on the target?

      As per your case, refer the following logical codings :

    1.you can try for save/restore serializable object to/from file like below :

    public void SerializeObject<T>(T serializableObject, string fileName)
        {
            if (serializableObject == null) { return; }
    
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
                using (MemoryStream stream = new MemoryStream())
                {
                    serializer.Serialize(stream, serializableObject);
                    stream.Position = 0;
                    xmlDocument.Load(stream);
                    xmlDocument.Save(fileName);
                    stream.Close();
                }
            }
            catch (Exception ex)
            {
                //Log exception here
            }
    }

    2.you can try for deserialize xml file to form List<T> like below :

    public static T FromXML<T>(string xml)
    {
      using (StringReader stringReader = new StringReader(xml))
      {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(stringReader);
      }
    }
    
    public string ToXML<T>(T obj)
    {
      using (StringWriter stringWriter = new StringWriter(new StringBuilder()))
      {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        xmlSerializer.Serialize(stringWriter, obj);
        return stringWriter.ToString();
      }
    }

    --
    with regards,
    Edwin

    Wednesday, May 6, 2015 10:11 PM
  • User-865231019 posted

    I'm obviously out of my depth with this because I don't understand this. 

    Is the code just for reading the file and then saving it back to an XML file without making any changes to it? So deserializing it in to a MemoryStream and then serializing it back to a String which can then be saved as an XML file?

    If that is the case, then great thanks for that, but the real issue I have is how to change the formatting of the XML to the new schema so that it's accepted by the Umbraco importer. 

    So, 

    1. Read in the XML file in to a memory stream (which looks like that is what your answer does)
    2. Take all the data from the import and shape it in to the BlogML schema
    3. Save the newly formatted stream in to a new XML file which validates to BlogML standards.

    Thursday, May 7, 2015 4:31 AM
  • User-865231019 posted

    I've ended up going back to basics, following some Pluralsight tutorials and I've decided to rebuild it as a Console App rather than a Web App.

    I'm also going to try and use the List option you supplied and see if I can get my thing to work, but if anyone has any other comments or can help me any further, I would be really grateful! 

    Think I might have jumped in to the deepend! 

    Thursday, May 7, 2015 10:41 AM
  • User-865231019 posted

    A couple of steps forward today. I've now serialized my XML file using

    public static T FromXML<T>(string xml)
    {
      using (StringReader stringReader = new StringReader(xml))
      {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(stringReader);
      }
    }
    
    public string ToXML<T>(T obj)
    {
      using (StringWriter stringWriter = new StringWriter(new StringBuilder()))
      {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        xmlSerializer.Serialize(stringWriter, obj);
        return stringWriter.ToString();
      }
    }

    Thanks for that!

    I've now got a foreach loop working so that it outputs the blog title and blog content

      class Program
        {
            static void Main(string[] args)
            {
                string xmlPath = @"C:\MyPath\export.xml";
    
               Data blogImport = new Data();
               blogImport = serialization.FromXML<Data>(xmlPath);
    
            //   blog blogExport = new blog();
                var i = 0;
    
                foreach (var blog in blogImport.BlogPost)
                {
    
                    string blogTitle = blogImport.BlogPost[i].TitlePart.Title.ToString();
                    string blogContent = blogImport.BlogPost[i].BodyPart.Text.ToString();
    
                    Console.WriteLine(blogTitle);
                    Console.WriteLine(blogContent);
                    Console.WriteLine("");
    
                    i++;
                }
    
               Console.WriteLine("");
               Console.ReadKey();
    
               
            }
    
        }

    So that should at least give me a way of collecting the information for the new XML file. 

    What is the best way to create this new XML file now? Linq? Manually create the XML file in the format that I need? 

    Friday, May 8, 2015 10:04 AM
  • User1711366110 posted

    What is the best way to create this new XML file now? Linq? Manually create the XML file in the format that I need? 

      As per this case, you can try the following logic :

    private void addToXml()
    {
     XDocument xmlDoc = XDocument.Load(@"C:\MyPath\export.xml");
      Data blogImport = new Data();
      blogImport = serialization.FromXML<Data>(xmlPath);
    
      xmlDoc.Element("Root").Add(
      new XElement("Parent", 
      new XElement("Child1", value1),
      new XElement("Child2", value2), 
      new XElement("Child3", value3)
     ));
     
     xmlDoc.Save("export.xml");
     readXml();
    }
    

    --
    with regards,
    Edwin

    Tuesday, May 19, 2015 1:17 AM