0

I've been working on a home project to convert an exported XML file from my current CMS (Orchard CMS) which has all my blog posts in it to a new structure (BlogML) so that I can import it in to Umbraco.

So far I have greated the new XML structure with Linq and it's an empty shell of attributes and elements, but I'm having a couple of issues with the finer points.

An extract of the Orchard CMS XML is:

  <BlogPost Id="/alias=The Blog\/2012\/09\/10\/on-starters-orders" Status="Published">
  <TextField.Excerpt />
  <TaxonomyField.Categories Terms="" />
  <TaxonomyField.Tags Terms="" />
  <BodyPart Text="&lt;p&gt;&#xD;&#xA;&#x9;Well, this is the first blog I have setup which will be something I will try and keep updated as much as possible.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;There are two reasons for the blog, well, two that I can think of just now. The first is to allow me to use my ASP.net programming skills on a more regular basis, not just for work. The second is to post my daily, weekly, monthly progress on my mission to get a qualifying time for Glasgow Commonwealth Games in 2014!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;You can have a look at my bio to find out more about me but what you wont find in there is what made me decide to give this huge challange a go.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Hopefully over the coming blogs I can share with you all my thoughts, my high and low moments and maybe in a round about sort of way, give something back to everyone who has given me support.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I&amp;#39;ve been running since 2008 when I was 18.5 stone (257lbs) and I needed to loose weight, since then I have found that I am actually not that bad at this running thing! In 2008 after I had ran Edinburgh Marathon and raised money for the RNLI,&amp;nbsp;I visited my local running club, Pitreavie AAC, and was welcomed with&amp;nbsp;open arms but was told that I may struggle for the longer distances as my pace was a bit slower than the others. This was my first challange, become faster and not the last one home on a Tuesday or Thursday evening.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Over time I started to progress through the groups, always pushing and always aiming for the top group, the really fast guys and girls. It took me a while but eventually I got there and in the process became the Team Manager for the Pitreavie AAC Road Runners, a role which I have had for the past 2 years.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;My pace is much quicker than when I first joined the club but on a national level, I still have some way to go! After the Olympic games it got me thinking, what would it take to get to an Olympics, then I scaled by dreams down a bit, for a bit anyway, then I thought, what would it take to get in to the Commonwealth Games. After a quick search on the interweb I found the qualifying time for the marathon distance for the Scottish Athletics. 2:19:00, two hours and nineteen minutes, that exquates to 5 minutes 18seconds a mile!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;At this point you would expect someone to go, that&amp;#39;s crazy pace, I will never manage that, but then you haven&amp;#39;t met me or if you have, you will know what I said next.....I can do that!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;After a chat with my fiancee, a number of emails and phone calls were made, first to find a coach, then&amp;nbsp;to find someone to give me nutritional advice and then a physio. The rest is history, I am now training to get a qualifying time for the Commonwealth Games!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;&amp;nbsp;&lt;/p&gt;&#xD;&#xA;" />
  <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="&lt;p&gt;&#xD;&#xA;&#x9;Coach wanted to see what I can do just now, one mile on the track, nothing more, nothing less. There was a local meet at Pitreavie AAC and there just so happened to be a one mile race scheduled. Here was my chance to see what I could do.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I went for a warm up about 20mins before the race and then waited, waited a bit more and by the time the race was called to start, I had cooled down again! Not great but no excuses. On your marks, and then bang! off went the gun. I started off well but I was tense, nervous and not running fluid. It was strange running round a track where people can see every move you make, every stride and every breath you make! Round and round, watching. I was quite comfortably in last place with no hope of catching my club mate which is probably the fastest road runner the club has and he was even trailing from the front runners - these guys were quick!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I finished in 5:24.09 which isnt too bad! I expected worse and that is after a tough session on Thursday.&amp;nbsp;12 x 400m with 100m recovery between each rep.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;After the race I ran back home (18miles) and it hurt! It was really windy over the Forth Road Bridge, the pace wasn&amp;#39;t too bad considering but the last 2 miles of the run home were the worst, I think I was dehydrated more than anything.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Will have a rest day tomorrow, apart from BodyPump class, and then get to club on Tuesday.&lt;/p&gt;&#xD;&#xA;" />
  <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>

and what I need to do is get some of this information in to

 <posts>
<post id="" date-created="" date-modified="" approved="true" post-url="" type="normal" hasexcerpt="false" views="" is-published="true">
  <title type="text"><![CDATA[]]></title>
  <content type="text"><![CDATA[]]]></content>
  <post-name type="text"><![CDATA[]]></post-name>
  <authors>
    <author ref="Owain" />
  </authors>
  <categories>
    <category ref="1" />
  </categories>
  <tags>
    <tag ref="" />
  </tags>
</post>

and loop through the original XML file to populate the Date-created from the CommonPart CreatedUTC, Content from BodyPart Text etc. Basically I reckon once I can get one bit of information I should be able to work out how to do the rest.

So far I have coded this:

  protected void btnBuild_Click(object sender, EventArgs e)
    {
        XElement xe = XElement.Load(Server.MapPath("test.xml"));

        XName blogPost = XName.Get("BlogPost");
        XName bodyPart = XName.Get("BodyPart");



        //foreach (var bodyPartElement in xe.Elements(blogPost))
        //{
        //    var locElement = bodyPartElement.Element(bodyPart);
        //    string textElement = locElement.LastAttribute.ToString();
        //    string newText = textElement.Remove(0, 7);

        //    System.Diagnostics.Debug.WriteLine(newText);

        //}

        XElement contacts =
            new XElement("blog",
                new XAttribute("root-url", "testing"),
                new XAttribute("date-created", DateTime.Now.ToString()),


                new XElement("title",
                    new XAttribute("type", "text"),
                    new XCData("BlogML 2.0 Sample Blog")
                ),

                new XElement("sub-title",
                        new XAttribute("type", "text"),
                        new XCData("This is a sample blog content for BlogML 2.0")

                    ),

                new XElement("authors",
                    new XElement("author",
                        new XAttribute("id", "2100"),
                        new XAttribute("date-created", DateTime.Now.ToString()),
                        new XAttribute("date-modified", DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("email", "owaingdwilliams@gmail.com"),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Owain")
                            )
                        )
                        ),

                        new XElement("extended-properties",
                    new XElement("property",
                        new XAttribute("name", "CommentModeration"),
                        new XAttribute("value", "anonymous")
                        ),

                        new XElement("property",
                            new XAttribute("name", "SendTrackback"),
                            new XAttribute("value", "true")

                        )),

                        new XElement("categories",
                    new XElement("category",
                        new XAttribute("id", "1"),
                        new XAttribute("date-created", System.DateTime.Now.ToString()),
                        new XAttribute("date-modified", System.DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("parentref", ""),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Owain's Blog")

                        )
                        ),

                        new XElement("category",
                        new XAttribute("id", "2"),
                        new XAttribute("date-created", System.DateTime.Now.ToString()),
                        new XAttribute("date-modified", System.DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("parentref", ""),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Mandy's Blog")

                        )
                        )),


                        //Blog Post Section
                        //TODO create a loop to parse each post. 

                        new XElement("posts",
                            new XElement("post",
                                new XAttribute("id", ""),
                                new XAttribute("date-created",""),
                                new XAttribute("date-modified", ""),
                                new XAttribute("approved","true"),
                                new XAttribute("post-url",""),
                                new XAttribute("type","normal"),
                                new XAttribute("hasexcerpt","false"),
                                new XAttribute("views",""),
                                new XAttribute("is-published","true"),
                                new XElement("title",
                                    new XAttribute("type","text"),
                                    new XCData("")),


                                    new XElement("content",
                                    new XAttribute("type","text"),
                                    new XCData("")                                                                                
                                    ),



                                new XElement("post-name",
                                    new XAttribute("type","text"),
                                    new XCData("")),
                                new XElement("authors",
                                    new XElement("author",
                                        new XAttribute("ref","Owain")
                                )),
                                new XElement("categories",
                                    new XElement("category",
                                        new XAttribute("ref","1"))
                                    ),
                                    new XElement("tags",
                                        new XElement("tag",
                                            new XAttribute("ref",""))
                                        )


                                    )));
        contacts.Save(Server.MapPath("Build.xml"));

Hope there is help out there please. Thanks.

UPDATE

I've gone down the Serialization route but now getting an error there’s an error in the Xml document at (1,1) which is within the XML file.

My code has been taken from MSDN examples:

protected void btnSerialization_Click(object sender, EventArgs e)
    {
        string path = Server.MapPath("export.xml");
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "Data";
        xRoot.IsNullable = true;

        // Create an instance of the XmlSerializer specifying type and namespace.
        XmlSerializer ser = new XmlSerializer(typeof(Data), xRoot);
        ser.UnknownNode += new
        XmlNodeEventHandler(ser_UnknownNode);
        ser.UnknownAttribute += new
        XmlAttributeEventHandler(ser_UnknownAttribute);




        // A FileStream is needed to read the XML document.
        FileStream fs = new FileStream(path, FileMode.Open);
        XmlReader reader = XmlReader.Create(fs);

        Data bl;


        // Declare an object variable of the type to be deserialized.
        bl = (Data)ser.Deserialize(fs);

        lblInfo.Text = bl.BlogPost.ToString();

        fs.Close();



    }

    private void ser_UnknownNode (object sender, XmlNodeEventArgs e)
    {
        lblInfo.Text = "Unknown Node"+e.Name+"\t"+e.Text;
    }
    private void ser_UnknownAttribute(object sender, XmlAttributeEventArgs e)
    {
        System.Xml.XmlAttribute attr = e.Attr;
        lblInfo.Text = "Unknown Att" + attr.Name + "\t" + attr.Value;
    }

The Path to the email file seems to be fine as it finds the XML file, I've used the xsd.exe file to create the .cs and used Visual Studio to create the schema for the XML file. I'm feeling like I'm just wondering around this without any clear idea on how to fix it.

UPDATE 2

          string path = Server.MapPath("export.xml");
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "Data";
        xRoot.IsNullable = true;


        Data myObject = new Data();
        XmlSerializer ser = new XmlSerializer(myObject.GetType(),xRoot);
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
            XmlTextReader reader = new XmlTextReader(fs);
            myObject = (Data)ser.Deserialize(reader);
            lblInfo.Text = myObject.BlogPost[1].BodyPart.Text;
        }

This now reads the XML file and displays the first bodyPart of the first blog! Almost there! Thanks for the help.

Owain Williams
  • 417
  • 1
  • 3
  • 11

2 Answers2

2

All this code is over complicated. I suggest you use xml serialization to import your data from xml, manipulate your data through c# classes and output it in xml format. See this post for more informations.

Update for more details about the way to do it:

MyClass myObject = new MyClass;
XmlSerializer ser = new XmlSerializer(myObject.GetType());
using (FileStream fs = new FileStream(FilePath, FileMode.Open))
{
    XmlTextReader reader = new XmlTextReader(fs);
    myObject = (MyClass)ser.Deserialize(reader);
}
Community
  • 1
  • 1
Fjodr
  • 919
  • 13
  • 32
  • Thanks @Fjodr I've gone down the route of the serialization but hit a couple of other problems. I've updated my original post and would appreciate any help you have to offer. – Owain Williams Apr 25 '15 at 11:16
  • There may be an error about the structure of your xml file. Try to open it in IE browser to see if there are. Also, I updated my answer to show you how I deserialize. – Fjodr Apr 27 '15 at 13:33
  • Brilliant! Thanks! I've now got it mostly working - well, I've got it reading the first bit of information which I can then hopefully write in to the new XML file. – Owain Williams Apr 28 '15 at 12:51
0

How about this:

//Blog Post Section
//TODO create a loop to parse each post. 

new XElement("posts",
    xe
    .Elements("BlogPost")
    .Select(x => 
        new XElement("post",
            new XAttribute("date-created", x.Element("CommonPart").Attribute("CreatedUtc").Value),
            new XElement("content",
                new XAttribute("type","text"),
                new XCData(x.Element("BodyPart").Attribute("Text").Value)))));

This example only maps a couple of fields (I did not know how the rest were supposed to be mapped) but I think it should get you going in the right direction. Oh, and I included the create a loop to parse each post comment to indicate where in your example you would implement this, not to imply that we are using a loop to solve this.

Jason Boyd
  • 6,839
  • 4
  • 29
  • 47