From : XSLT Sorting - how to sort xml childnodes inside a parent node with an attribute
I'm using the Jenkins' CppCheck plugin that parse a XML log file. However CppCheck puts everything as it comes and it is not sorted in any way. I'd like to sort the XML log file by the 'location' tag.
tl;dr : XML hierarchy is 'results/errors/error/location', I want to sort 'error' according to 'location/@file' and 'location/@line'
I'm using this :
@echo off
"C:\Program Files (x86)\xmlstarlet-1.5.0\xml.exe" tr ".\cppcheck_log.xslt" ".\cppcheck_log.xml" 1>".\cppcheck_log_sorted.xml"
With the following XLST transformation rule :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="errors">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*">
<xsl:sort select="@file" data-type="text" order="ascending"/>
<xsl:sort select="@line" data-type="number" order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But it doesn't work. What CppCheck produce is :
<?xml version="1.0" encoding="UTF-8"?>
<results version="2">
<cppcheck version="1.63.1"/>
<errors>
<error id="variableScope" severity="style" msg="The scope of the variable 'i' can be reduced." verbose="The scope of the variable 'i' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced:
void f(int x)
{
int i = 0;
if (x) {
// it's safe to move 'int i = 0;' here
for (int n = 0; n < 10; ++n) {
// it is possible but not safe to move 'int i = 0;' here
do_something(&i);
}
}
}
When you see this message it is always safe to reduce the variable scope 1 level.">
<location file="toto\test.c" line="50"/>
</error>
<error id="unreadVariable" severity="style" msg="Variable 'size' is assigned a value that is never used." verbose="Variable 'size' is assigned a value that is never used.">
<location file="tata\done.c" line="25"/>
</error>
</errors>
</results>
What I would like to get :
<?xml version="1.0" encoding="UTF-8"?>
<results version="2">
<cppcheck version="1.63.1"/>
<errors>
<error id="unreadVariable" severity="style" msg="Variable 'size' is assigned a value that is never used." verbose="Variable 'size' is assigned a value that is never used.">
<location file="tata\done.c" line="25"/>
</error>
<error id="variableScope" severity="style" msg="The scope of the variable 'i' can be reduced." verbose="The scope of the variable 'i' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced:
void f(int x)
{
int i = 0;
if (x) {
// it's safe to move 'int i = 0;' here
for (int n = 0; n < 10; ++n) {
// it is possible but not safe to move 'int i = 0;' here
do_something(&i);
}
}
}
When you see this message it is always safe to reduce the variable scope 1 level.">
<location file="toto\test.c" line="50"/>
</error>
</errors>
</results>
What I currently get is still unsorted (XMLStarlet flatten me the first error message in one line) :
<?xml version="1.0" encoding="UTF-8"?>
<results version="2">
<cppcheck version="1.63.1"/>
<errors>
<error id="variableScope" severity="style" msg="The scope of the variable 'i' can be reduced." verbose="The scope of the variable 'i' can be reduced. Warning: Be careful when fixing this message, especially when there are inner loops. Here is an example where cppcheck will write that the scope for 'i' can be reduced: void f(int x) { int i = 0; if (x) { // it's safe to move 'int i = 0;' here for (int n = 0; n < 10; ++n) { // it is possible but not safe to move 'int i = 0;' here do_something(&i); } } } When you see this message it is always safe to reduce the variable scope 1 level.">
<location file="toto\test.c" line="50"/>
</error>
<error id="unreadVariable" severity="style" msg="Variable 'size' is assigned a value that is never used." verbose="Variable 'size' is assigned a value that is never used.">
<location file="tata\done.c" line="25"/>
</error>
</errors>
</results>
Not nice.
I'm a rookie in XML transformation, so any help is welcome.
Thanks for the feedback...
Use one of the following options:
References