简体   繁体   中英

xsltproc add text before and after multiple files

I'm using the xsltproc utility to transform multiple xml test results into pretty printed console output using a command like the following.

xsltproc stylesheet.xslt testresults/*

Where stylesheet.xslt looks something like this:

<!-- One testsuite per xml test report file -->
<xsl:template match="/testsuite">
  <xsl:text>begin</xsl:text>
  ...
  <xsl:text>end</xsl:text>
</xsl:template>

This gives me an output similar to this:

begin
TestSuite: 1
end
begin
TestSuite: 2
end
begin
TestSuite: 3
end

What I want is the following:

begin
TestSuite: 1
TestSuite: 2
TestSuite: 3
end

Googling is turning up empty. I suspect I might be able to merge the xml files somehow before I give them to xsltproc , but I was hoping for a simpler solution.

xsltproc transforms each specified XML document separately, as indeed is the only sensible thing for it to do because XSLT operates on a single source tree, and xsltproc doesn't have enough information to compose multiple documents into a single tree. Since your template emits text nodes with the "begin" and "end" text, those nodes are emitted for each input document.

There are several ways you could arrange to have just one "begin" and one "end". All of the reasonable ones start with lifting the text nodes out your template for <testsuite> elements. If each "TestSuite:" line in the output should correspond to one <testsuite> element then you'll need to do that even if you physically merge the input documents.

One solution would be to remove the responsibility for the "begin" and "end" lines from XSLT altogether. For example, remove the xsl:text elements from the stylesheet and write a simple script such as this:

echo begin
xsltproc stylesheet.xslt testresults/*
echo end

Alternatively, if the individual XML files do not start with XML declarations, then you might merge them dynamically, by running xsltproc with a command such as this:

{ echo "<suites>"; cat testresults/*; echo "</suites>"; } \
    | xsltproc stylesheet.xslt -

The corresponding stylesheet might then take a form along these lines:

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

  <xsl:template match="/suites">
    <!-- the transform of the root element produces the "begin" and "end" -->
    <xsl:text>begin&#x0A;</xsl:text>
    <xsl:apply-templates select="testsuite"/>
    <xsl:text>&#x0A;end</xsl:text>
  </xsl:template>

  <xsl:template match="testsuite">
    ...
  </xsl:template>
</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM