I have the following xml (as example)
<?xml version="1.0"?>
<gameList>
<game>
<path>./sunsetbl.zip</path>
<name>sunsetbl</name>
<playcount>8</playcount>
<lastplayed>20180924T214132</lastplayed>
</game>
<game>
<path>./ssriders.zip</path>
<name>Sunset Riders (4 Players ver EAC)</name>
<playcount>4</playcount>
<lastplayed>20181030T013801</lastplayed>
</game>
<game>
<path>./kof97.zip</path>
<name>The King of Fighters '97 (NGM-2320)</name>
<playcount>2</playcount>
<lastplayed>20181030T035949</lastplayed>
</game>
<game>
<path>./dino.zip</path>
<name>Cadillacs and Dinosaurs (World 930201)</name>
<favorite>true</favorite>
<playcount>26</playcount>
<lastplayed>20181030T043441</lastplayed>
</game>
<game>
<path>./kof98n.zip</path>
<name>kof98n</name>
<playcount>1</playcount>
<lastplayed>20181031T001024</lastplayed>
</game>
</gameList>
Well, I'm trying to do a sh script and use xmlstarlet on it. For each game node I want to copy the path node and insert it into a new node called description, and if description already exists, concatenate it to the existing text there.
I'm really noob on this and this is what I was able to do until now.
#!/bin/bash
set -e
shopt -s nullglob
for file in *.xml
do
FILENAME=`xmlstarlet sel -t -m "/gameList/game" -v path $file`;
echo "Appending $FILENAME into description on $file";
xmlstarlet ed -L -s "/gameList/game" -t elem -n description -v "$FILENAME" $file;
done
Of course, the results sucks, all the path values are together in one line and copied to each game node, this is what it shows
<?xml version="1.0"?>
<gameList>
<game>
<path>./sunsetbl.zip</path>
<name>sunsetbl</name>
<playcount>8</playcount>
<lastplayed>20180924T214132</lastplayed>
<description>./sunsetbl.zip./ssriders.zip./kof97.zip./dino.zip./kof98n.zip</description>
</game>
<game>
<path>./ssriders.zip</path>
<name>Sunset Riders (4 Players ver EAC)</name>
<playcount>4</playcount>
<lastplayed>20181030T013801</lastplayed>
<description>./sunsetbl.zip./ssriders.zip./kof97.zip./dino.zip./kof98n.zip</description>
</game>
<game>
<path>./kof97.zip</path>
<name>The King of Fighters '97 (NGM-2320)</name>
<playcount>2</playcount>
<lastplayed>20181030T035949</lastplayed>
<description>./sunsetbl.zip./ssriders.zip./kof97.zip./dino.zip./kof98n.zip</description>
</game>
<game>
<path>./dino.zip</path>
<name>Cadillacs and Dinosaurs (World 930201)</name>
<favorite>true</favorite>
<playcount>26</playcount>
<lastplayed>20181030T043441</lastplayed>
<description>./sunsetbl.zip./ssriders.zip./kof97.zip./dino.zip./kof98n.zip</description>
</game>
<game>
<path>./kof98n.zip</path>
<name>kof98n</name>
<playcount>1</playcount>
<lastplayed>20181031T001024</lastplayed>
<description>./sunsetbl.zip./ssriders.zip./kof97.zip./dino.zip./kof98n.zip</description>
</game>
</gameList>
I would gladly appreciate any help on this.
If you can use a separate XSLT file, the solution would be as follows.
Use this XSLT file (here named trans.xslt
):
<?xml version="1.0"?>
<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>
<!-- Add 'path' value to existing 'description' element -->
<xsl:template match="description">
<xsl:copy>
<xsl:value-of select="concat(.,../path)" />
</xsl:copy>
</xsl:template>
<!-- Create new 'description' element -->
<xsl:template match="game[not(description)]">
<xsl:copy>
<xsl:copy-of select="node()|@*" />
<description>
<xsl:value-of select="path" />
</description>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
And call it with this script:
#!/bin/bash
set -e
shopt -s nullglob
for file in *.xml
do
xmlstarlet tr trans.xslt "$file" > "$file.new.xml"
done
This create new files with the extension filename.new.xml
.