1

I have a client who would like to have drop down list added to his registration form that lists all of the provinces in the world by their country code. To that end, he gave me this file. Unfortunately, the structure of the data will not work for what I need to do. Below is the structure I'd like to have. Is there some way to automatically restructure the data, perhaps by using XSLT or something similar? Thanks!

<countries>
  <country code="US">
    <region>Alaska</region>
    <region>California</region>
  </country>
</countries>

6 Answers6

1

This is easily accomplished by adding a single template to the XSLT identity transform:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="node() | @*">
       <xsl:copy>
          <xsl:apply-templates select="node() | @*" />
       </xsl:copy>
   </xsl:template>

   <xsl:template match="countries/*">
       <country code="{name()}">
          <xsl:apply-templates select="region"/>
       </country>
   </xsl:template>

</xsl:stylesheet>
Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
0

If I had to convert that file, I'd just write a quick helper console app, deserialize the current file into an object corresponding to the current format, then just run through a loop and drop the data into a new object heirarchy corresponding to your new format above, and then serialize it back out to XML.

This way if I ever had to reimport the same file again I could just re-run my transformation app.

Bob Palmer
  • 4,714
  • 2
  • 27
  • 31
0

Maybe this can help you?

Convert XML Structure

Mattias
  • 3,907
  • 4
  • 28
  • 50
0

You can use your favorite regular expressions tool to transform the file. For example in .NET you can use:

string result = Regex.Replace(Regex.Replace(input, "<(..)>", "<country code=\"$1\">"), "</..>", "</country>");

$1 refers to the string matched by the first matching group "(..)".

Here is your converted file

See the web site regular-expressions.info for more information.

Orlin
  • 308
  • 2
  • 4
0

My XSLT-fu isn't up to it, but yes, you can do it with XSLT.

You're actually only trying to do one clever thing and that's to convert the country code tags into tags.

Its straightforward to iterate over a list of children of a particular node, you can get the tag name of the current node and you can output more or less whatever you want... where I'm uncertain (it not being anything I've ever had to do) is the exact incantation for plucking the node name.

Edit: Too good a question to let go (learning opportunity)

The missing bit of the answer is, of course, on stackoverflow

So that gives you this (based on what I know... I'm sure the copy of regions can be simplified, but I don't know how!):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="countries" />

        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="countries">
        <countries>
            <xsl:for-each select="child::*">
                <country code="{local-name()}">
                    <xsl:apply-templates select="region" />
                </country>
            </xsl:for-each>
        </countries>
    </xsl:template>

    <xsl:template match="region">
        <region>
            <xsl:value-of select="."/>
        </region>
    </xsl:template>

</xsl:stylesheet>

Suggestions for improvements welcomed - will amend as appropriate!

Community
  • 1
  • 1
Murph
  • 9,985
  • 2
  • 26
  • 41
0

I should have checked here for answers first (didn't receive an e-mail notification), but I managed to write a small ASP/VB program to do this. Thank you guys for your answers, though! Had I checked here first, I would have save myself some time. At least I have a program I can reuse now.