Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write at the end of an xml

Tags:

java

xml

xslt

i have multiple Xml files, in a List<File>. What i want is to transform those xml into one Xml with an Xsl :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes"/>

<xsl:template match="testsuites">
    <xsl:call-template name="summary"/>
</xsl:template>

 <xsl:template name="summary">
           <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
         <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
         <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
 <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
         <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
          <xsl:attribute name="class">
                <xsl:choose>
                    <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
                    <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
                </xsl:choose>
            </xsl:attribute>
         <Build>
          <NombreTest><xsl:value-of select="$testCount"/></NombreTest>
          <Failures><xsl:value-of select="$failureCount"/></Failures>
          <Erreurs><xsl:value-of select="$errorCount"/></Erreurs>
         <PercentSucces><xsl:call-template name="display-percent">
                    <xsl:with-param name="value" select="$successRate"/>
                </xsl:call-template></PercentSucces>
          <ExecTime><xsl:call-template name="display-time">
                   <xsl:with-param name="value" select="$timeCount"/>
                </xsl:call-template> </ExecTime>
          </Build> 
       </xsl:template>

<xsl:template match="failure">
    <xsl:call-template name="display-failures"/>
</xsl:template>

<xsl:template match="error">
    <xsl:call-template name="display-failures"/>
</xsl:template>

<xsl:template name="display-time">
    <xsl:param name="value"/>
    <xsl:value-of select="format-number($value,'0.000')"/>
</xsl:template>

<xsl:template name="display-percent">
    <xsl:param name="value"/>
    <xsl:value-of select="format-number($value,'0.00%')"/>
</xsl:template>

<xsl:template name="display-failures">
    <xsl:choose>
        <xsl:when test="not(@message)">N/A</xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="@message"/>
        </xsl:otherwise>
    </xsl:choose>
 </xsl:template>

</xsl:stylesheet>

My problem is that when i am looping and apply the transform with a TransformerFactory it always erase the output XML. I want to edit the output instead.

I know that i can do it in java with a temporary XML and after merge it, but i'm almost sure that it is possible in XSL?

Thanks for helping

like image 588
Theo Avatar asked Nov 14 '22 04:11

Theo


1 Answers

You need to pass all document URLs within a single external parameter and you will typically have a transformation like this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 
 <xsl:param name="pdocNames">
  <name>doc1.xml</name>
  <name>doc2.xml</name>
  <name>doc3.xml</name>
 </xsl:param>
 
    <!-- you can directly use $pdocNames/name
        if the param is provided externally -->
 <xsl:variable name="vDocNames" select=
  "document('')/*/xsl:param[]@name='pdocNames']/name"/>
    
 <xsl:template match="/">
     <combinedDocs>
    <xsl:copy-of select="document($vDocNames)"/>
     </combinedDocs>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), it performs the following:

  1. Obtains the name elements that contain the provides in the parameter $pdocNames document URIs. These elements are contained in the variable vDocNames.

  2. Creates the top element for the output document (in this case named combinedDocs).

  3. Copies all XML documents, whose URIs are in the name elements contained in the vDocNames variable. The standard XSLT function document() is used here.

Do note:

The URLs of all wanted XML documents must be passed externally via a parameter to the transformation. It is vendor-dependent how to pass a parameter to the transformation. You need to read the documentation provided for your particular XSLT processor.

like image 52
Dimitre Novatchev Avatar answered Nov 16 '22 17:11

Dimitre Novatchev