2

I was wondering if anyone knew if there was a simple way to change all of my strings in my xml file to arrays?

Example:

//This is the string I need to change:
<string name="sample1">value1, value2, value3, value4, value5</string>
//This is the way I need it to be:
<array name="sample1">
    <item>value1</item>
    <item>value2</item>
    <item>value3</item>
    <item>value4</item>
    <item>value5</item>
</array>

My problem is not that I do not know how to manually do it. But I am looking for a way to simulate this process more easily because I have 120 strings with 25-90 values in each.

A good example would be converting multiple images extentions with a single click using an add-on to GIMP that simulates that process for you for each image.

Would anyone who understands what I am asking, know a way to do this for string to array?

Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
zack2o
  • 25
  • 1
  • 6
  • you could use XSLT since you are dealing with XML – Peter Aug 23 '12 at 05:03
  • http://en.m.wikipedia.org/wiki/XSLT. I can give you a transformation in xslt in about an hour if you want to give it a try – Peter Aug 23 '12 at 05:09
  • I would like that if its not too much trouble. I read up on that and it sounds like what i need, but i couldn't see where it can convert the string into an array. – zack2o Aug 23 '12 at 05:12
  • @peter can we convert an XML to another XML using XSLT? – aravind Aug 23 '12 at 05:26
  • @aravind: yes, you use XSLT to convert XML to XML, HTML or Text – Peter Aug 23 '12 at 06:03

2 Answers2

3

This XSLT:

<?xml version="1.0" encoding="UTF-8"?>

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

<xsl:template match="/">
    <array>
        <xsl:attribute name="name">
            <xsl:value-of select="string/@name"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </array>
</xsl:template>

<xsl:template match="string/text()" name="tokenize">
    <xsl:param name="text" select="."/>
    <xsl:param name="sep" select="','"/>
    <xsl:choose>
        <xsl:when test="not(contains($text, $sep))">
            <item>
                <xsl:value-of select="normalize-space($text)"/>
            </item>
        </xsl:when>
        <xsl:otherwise>
            <item>
                <xsl:value-of select="normalize-space(substring-before($text, $sep))"/>
            </item>
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $sep)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

applied to this XML:

<?xml version="1.0" encoding="UTF-8"?>
<string name="sample1">value1, value2, value3, value4, value5</string>

gives this output:

<?xml version="1.0" encoding="UTF-8"?>
<array name="sample1">
<item>value1</item>
<item>value2</item>
<item>value3</item>
<item>value4</item>
<item>value5</item>
</array>

The XSLT is using a recursive template going through your string values and splitting them at the comma.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Peter
  • 1,786
  • 4
  • 21
  • 40
  • Nice answer. But be careful when normalizing the string values, maybe there are whitespaces allowed within the data. – Philipp Aug 23 '12 at 09:52
  • Okay so i ran the xsl transformation using what you have supplied, and I get an Error: res\layout\NewStylesheet.xsl: **No embedded stylesheet instruction for file: file:/C:/Users/MyName/Documents/My Dropbox/Personal/workspace/MySampleApp/res/values/strings.xml** – zack2o Aug 23 '12 at 20:59
  • hi zack2o, in the source xml before place this line: and in href give your file name. regards, peter – Peter Aug 23 '12 at 21:30
  • okay i did that and i get this error now: 17:39:13,667 **ERROR [main] JAXPSAXProcessorInvoker - Error checking type of the expression 'funcall(tokenize, [step("self", -1), literal-expr(,\s*)])'.** 17:39:13,669 ERROR [main] **JAXPSAXProcessorInvoker - Could not compile stylesheet** – zack2o Aug 23 '12 at 21:39
  • Was functioning properly, but now after i run it, nothing happens. No new strings.out.xml or even any errors. Any idea why it all of a suddden has stopped doing anything? – zack2o Aug 24 '12 at 00:43
  • Fixed it, this is now working as intended and thank you very much for your help! – zack2o Aug 24 '12 at 01:04
  • Hi zack2o, sorry I could not answer anymore, it was already night for me. Glad you got it running. All the best with your new knowledge! Best regards, Peter – Peter Aug 24 '12 at 06:11
1

This can be done with XSLT 2.0 as simply as:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <array name="{@name}">
     <xsl:for-each select="tokenize(., ',\s*')">
      <item><xsl:value-of select="."/></item>
     </xsl:for-each>
    </array>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<string name="sample1">value1, value2, value3, value4, value5</string>

the wanted, correct result is produced:

<array name="sample1">
   <item>value1</item>
   <item>value2</item>
   <item>value3</item>
   <item>value4</item>
   <item>value5</item>
</array>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • seems like the same error for both, am i missing something: **No embedded stylesheet instruction for file: file:/C:/Users/MyName/Documents/My Dropbox/Personal/workspace/MySampleApp/res/values/strings.xml** – zack2o Aug 23 '12 at 21:02
  • It seems that you are trying to run the transformation in some weird way. A transformation needs to be in its own file -- not embedded in the XML file that is to be transformed. – Dimitre Novatchev Aug 23 '12 at 21:38