Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 08, 2012 @ 15:34
    Bo Damgaard Mortensen
    1

    Importing deep XML structure

    Hi all,

    I've just bought the CMSImport Pro package as I need to import a large amount of members to my Umbraco installation.

    The data I need to import comes from an XML structure that looks like this:

    <members> <member xmlns="mynamespace" id="1" status="1" active="1"> <shop> <notes/> <url>an url</url> <altUrl/> <description>asd asd</description> </shop> <customer> <someElement>somevalue</someElement>

    .... rest of XML omitted here ..

    When I set the XML source to this XML document in CMSImport, I'm only able to select the attributes on the member element and all the childelements (shop and customer), but not any of their child elements.

    Is this possible in same way with CMSImport Pro? Thing is, that I can't change the way the XML is structured as it comes from an external webservice.

    I've tried to create a custom DataAdapter for this, but with no luck :/

    Any help/hint is greatly appreciated!

    All the best,

    Bo

  • Richard Soeteman 4046 posts 12899 karma points MVP 2x
    Feb 08, 2012 @ 15:39
    Richard Soeteman
    0

    Hi Bo,

    Did you specify an XPath expression to query the members from this xml file? Can I have a peek at the complete xml structure somewhere?

    Thanks,

    'Richard

  • Stephen Roberts 47 posts 516 karma points c-trib
    Feb 08, 2012 @ 15:39
    Stephen Roberts
    0

    one possible solution for you is to create a c# app that opens the xml file, and then sticks members into a sql table in the database and get cmsimport to import from there.

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 08, 2012 @ 15:48
    Bo Damgaard Mortensen
    0

    Hi Richard and Stephen,

    Thanks for your fast replies! :)

    @Richard, I've tried some various XPath Expressions to query it, but the closets I've come so far is to the shop element by explicitly doing something like ./shop. It seems that the member element becomes the root element by default. Shouldn't it be the members element? :) So the xpath expression would look something like: //member/*/* ?

    @Stephen, that's definately a way of doing it, but to me it seems like double-trouble ;) Might have to go with such a solution if anything else fails.

    The complete XML structure for a member is as f

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 08, 2012 @ 15:49
    Bo Damgaard Mortensen
    0

    Ops, a bit too fast right there on the reply button ;)

    Xml structure:

    <members>
     <member xmlns="mydomain" status="1" aktiv="1">
      <shop>
       <firmaNoter/>
       <firmaUrl>www.domain.dk</firmaUrl>
       <firmaUrlAlternativ/>
       <firmaGodkendelsesDato>2002-03-07T12:00:00</firmaGodkendelsesDato>
       <firmaSidstKontrolleretDato>2010-08-30T12:00:00</firmaSidstKontrolleretDato>
       <firmaBeskrivelse>
        <p>Description company</p>
       </firmaBeskrivelse>
       <firmaTags/>
       <kategori>1943</kategori>
      </shop>
      <Kunde>
       <firmaSagsbehandler>0</firmaSagsbehandler>
       <firmaStatusBesked/>
       <firmaNavn>Company name</firmaNavn>
       <firmaSelskabsform/>
       <firmaEjer/>
       <firmaAdresse>Company address</firmaAdresse>
       <firmaPostnummer>28000</firmaPostnummer>
       <firmaBy>Company city</firmaBy>
       <firmaTelefon>12345678</firmaTelefon>
       <firmaEmail/>
       <firmaCvr>12345678</firmaCvr>
       <firmaEtableringsaar/>
       <firmaAntalAnsatte>5-24</firmaAntalAnsatte>
       <firmaStatement/>
       <firmaStatementWriter/>
      </Kunde>
      <kontakter>
       <kontakt kontaktId="1">
       <firmaKontaktperson>Contact name</firmaKontaktperson>
       <firmaKontaktTelefon/>
       <firmaKontaktMobil>12345678</firmaKontaktMobil>
       <firmaKontaktEmail>[email protected]</firmaKontaktEmail>
       </kontakt>
      </kontakter>
      <logo>
       <firmaLogo/>
       <firmaLogoCustomerUpload/>
      </logo>
      <SEO>
       <metaTitle>metatitle</metaTitle>
       <metaDescription>metadescription</metaDescription>
       <metaKeywords>meta keywords</metaKeywords>
       <seoTopText/>
       <seoBottomText/>
      </SEO>
     </member>
    </members>
    <members>

    Thanks again both of you!

  • Richard Soeteman 4046 posts 12899 karma points MVP 2x
    Feb 08, 2012 @ 16:14
    Richard Soeteman
    0

    Hi Bo,

    No By default CMSImport takes the children of the root. In that case you don't need to specify some xpath at all. What are the elements  you want to map for this import?

    Thanks,

    Richard 

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 08, 2012 @ 21:37
    Bo Damgaard Mortensen
    0

    Hi again Richard,

    I'm interested in getting the values that's in the third level elements. I.e.: <metaDescription>metadescription</metaDescription> and all attributes. Is this possible? :-) I've tried the following xpath expressions: */* and /*/* and ./*/* unfortunately without any results :/

    Have I missed something here? :)

    Thanks again,

    Bo

  • Richard Soeteman 4046 posts 12899 karma points MVP 2x
    Feb 09, 2012 @ 07:52
    Richard Soeteman
    0

    Hi Bo,

    Yes that is possible although not with a normal xPath. I've created a custom DataAdapter last year  for a client that had a very complex xml structure and flatten it down so it was supported by CMSImport.I can have a look at your DataAdapter might be easiest to send me the source (richard [at] soetemansoftware[dot]nl) Then I will have a look what is missing in your case and add the Methods that you can use to flatten down the xml structure.

    Best,

    Richard

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 13, 2012 @ 10:43
    Bo Damgaard Mortensen
    0

    Hi Richard,

    Thanks for your email! Much appreciated :-) I decided to simply try and flatten the XML documents structure which worked right away. The code I used for flattening a deep structured XML document is this:

    // Start flattening the XML output structure
                var doc = XDocument.Load(xml.CreateReader());
                var member = doc.Root.Element(NameSpace + "member");
                var descendants = member.Descendants().ToList();
    
                foreach (var nested in descendants.Elements().ToList())
                {
                    nested.Remove();
                }
    
                // Replace nodes
                member.ReplaceNodes(descendants);
    
                // Make sure empty tags are closed like this: <tag></tag> and not like this: <tag/>
                foreach (XElement elm in doc.Root.Element(NameSpace + "member").Descendants())
                {
                    if (string.IsNullOrEmpty(elm.Value))
                    {
                        elm.SetValue(string.Empty);
                    }
                }

    Thanks again!

    All the best

    Bo

  • Richard Soeteman 4046 posts 12899 karma points MVP 2x
    Feb 13, 2012 @ 11:19
    Richard Soeteman
    0

    Hi Bo,

    Great to hear that!

    Thanks,

    Richard

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Feb 13, 2012 @ 13:58
    Bo Damgaard Mortensen
    0

    Actually, there was a mistake in my above code - it only took the first occurence of

    Updated code (though not the prettiest solution):

    // Start flattening the XML output structure
                var doc = XDocument.Load(xml.CreateReader());
                var member = doc.Root.Element(NameSpace + "member");
    
                foreach (XElement xelm in doc.Root.Elements(NameSpace + "member"))
                {
                    var descendants = xelm.Descendants().ToList();
    
                    foreach (var nested in descendants.Elements().ToList())
                    {
                        nested.Remove();
                    }
    
                    // Replace nodes
                    xelm.ReplaceNodes(descendants);
                }
    
                foreach (XElement elm in doc.Root.Element(NameSpace + "member").Descendants())
                {
                    if (string.IsNullOrEmpty(elm.Value))
                    {
                        elm.SetValue(string.Empty);
                    }
                }

    Thanks again.

    - Bo

Please Sign in or register to post replies

Write your reply to:

Draft