1
votes

I have a big XML file the setup my application. There are a lot of comments for each configuration. I want to use a xsl to remove some comment according to the node.

<!-- if you need to use storage -->
<Storage>
    <!-- Oracle configuration
    <StorageDb database="OracleService"></StorageDb>
    -->
    <!-- SqlServer configuration
    <StorageDb database="SqlService"></StorageDb>
    -->
</Storage>

When I run my xsl i want to remove just the comments from Oracle configuration, so my result would be:

<!-- if you need to use storage -->
<Storage>
    <StorageDb database="OracleService"></StorageDb>

    <!-- SqlServer configuration
    <StorageDb database="SqlService"></StorageDb>
    -->
</Storage>

Any idea how I would make it?

3
Do you mean 'uncomment' some nodes? In other words: extract nodes from comments. - DRCB
Why do you want to use XSL for this? If there is a way to achieve such a transformation - it will be more or less ugly hack in XSL. I would propose simple search & replace for solving this problem. - DRCB
@DRCB: he said "according to some nodes," so maybe he wants to use XSLT to match on certain nodes. - LarsH

3 Answers

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

<xsl:template match="comment()">
    <xsl:value-of disable-output-escaping="yes" select="substring-after(.,'Oracle configuration')"/>
</xsl:template>
2
votes

If I got you right, what you ask is not removing comment nodes but analyze them and transform them to elements. You can do that with XSLT 2.0 and regex capabilities, but I don't think it's a good idea (not really robust).

An XSLT can help you anyway, but you first have to build a squelet for your configuration file. Let's imagine something like that :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    ...
    <Storage/>
    ...
</configuration>

Your XSLT could look like that :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:param name="service" select="'OracleService'"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Storage">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <StorageDb database="{$service}"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

The default behavior selects the value OracleService for the service parameter. It's possible to override this behavior by passing another value to the XSLT for this parameter.

Default result is :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <Storage><StorageDb database="OracleService"/></Storage>
    ...
</configuration>
1
votes

If you can use Saxon as your XSLT processor, then a robust way to do this (by which I mean, a method that doesn't rely on disable-output-escaping) would be to use saxon:parse() on the content of each comment node, after stripping out unwanted text. The result of saxon:parse() is an XML node, which can be output to the result document in the normal way.

E.g.:

<xsl:template match="comment()">
    <xsl:copy-of select="saxon:parse(substring-after(., 'configuration'))"/>
</xsl:template>

For more discussion, see XSLT parse text node as XML?