0

I have the following output from JUnit:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="Some Collection" tests="13" time="1.174">
  <testsuite name="Request 1"/>
  <testsuite name="Request 2">
    <testcase name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite name="Request 3">
    <testcase name="Status code is 200" time="0.056"/>
    <testcase name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

In this case testsuites is my root element. In order to convert it correctly into JSON, I need to add the following attribute to the testsuite and testcase elements: json:Array="true", I do that with an XSL:

<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:json="http://james.newtonking.com/projects/json">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="//testsuite">
  <xsl:copy>
   <xsl:attribute name="json:Array">true</xsl:attribute> 
   <xsl:apply-templates select="node()|@*" /> 
  </xsl:copy>
 </xsl:template>

 <xsl:template match="//testcase">
  <xsl:copy>
   <xsl:attribute name="json:Array">true</xsl:attribute> 
   <xsl:apply-templates select="node()|@*" /> 
  </xsl:copy>
 </xsl:template>
</xsl:transform>

This results in the following (valid) xml:

<testsuites name="Some Collection" tests="13" time="1.174">
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 1"/>
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 2">
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 3">
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Status code is 200" time="0.056"/>
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

but what I really want is the namespace moved to the root element so it can be used in child elements:

<testsuites xmlns:json="http://james.newtonking.com/projects/json" name="Some Collection" tests="13" time="1.174">
  <testsuite json:Array="true" name="Request 1"/>
  <testsuite json:Array="true" name="Request 2">
    <testcase json:Array="true" name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite json:Array="true" name="Request 3">
    <testcase json:Array="true" name="Status code is 200" time="0.056"/>
    <testcase json:Array="true" name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

How can I achieve that with XSLT?

1 Answer 1

1

You just need to add an template matching the parent element testsuites like below:

<xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://james.newtonking.com/projects/json">
    <xsl:output omit-xml-declaration="yes" indent="yes" />

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

    <xsl:template match="//testsuite">
        <xsl:copy>
            <xsl:attribute name="json:Array">true</xsl:attribute>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//testcase">
        <xsl:copy>
            <xsl:attribute name="json:Array">true</xsl:attribute>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//testsuites">
        <testsuites xmlns:json="http://james.newtonking.com/projects/json">
            <xsl:apply-templates select="node()|@*" />
        </testsuites>
    </xsl:template>
</xsl:transform>

http://xsltransform.net/asnmyQ

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.