Re: [xslt] XPath string functions question.



J.P.,

Try my solution below.

Derek

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:str="http://exslt.org/strings";
                extension-element-prefixes="str">

    <xsl:output mode="text"/>

    <!-- Basic search-and-replace function,
         based on http://exslt.org/str/functions/replace/ -->
    <xsl:template name="str:replace">
        <xsl:param name="string"/>
        <xsl:param name="search"/>
        <xsl:param name="replace"/>
        <xsl:choose>
            <xsl:when test="contains($string, $search)">
                <xsl:variable name="rest">
                    <xsl:call-template name="str:replace">
                        <xsl:with-param name="string" select="substring-after($string, $search)"/>
                        <xsl:with-param name="search" select="$search"/>
                        <xsl:with-param name="replace" select="$replace"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="concat(substring-before($string, $search), $replace, $rest)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$string"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- ========================================================= -->

    <!-- Make a comment and fill it in.  -->
    <xsl:template match="*" mode="make-comment">
        /*
         Following code was created from xml source tree:
         <xsl:apply-templates select="." mode="comment"/>
         */
    </xsl:template>

    <!-- Work recursively on child elements...  -->
    <xsl:template match="*" mode="comment">
        <xsl:copy>
            <xsl:apply-templates select="* | text()" mode="comment"/>
        </xsl:copy>
    </xsl:template>

    <!-- ... but check for text that could disrupt the comment. -->
    <xsl:template match="text()" mode="comment">
        <xsl:call-template name="str:replace">
            <xsl:with-param name="string" select="."/>
            <xsl:with-param name="search" select="'*/'"/>
            <xsl:with-param name="replace" select="'(star-slash)'"/>
        </xsl:call-template>
    </xsl:template>

    <!-- ========================================================= -->

    <!-- The necessary logic for the XML-to-C++ code translator -->
    <xsl:template match="mylist" mode="cpp-code">
        <xsl:text disable-output-escaping="yes">
        std::vector&lt;std::string&gt; mylist;
        </xsl:text>
        <xsl:apply-templates mode="cpp-code"/>
    </xsl:template>

    <xsl:template match="mylist/item" mode="cpp-code">
        <xsl:text>mylist.push_back("</xsl:text>
        <!-- Check for double-quotes that could kill your literal string -->
        <xsl:call-template name="str:replace">
            <xsl:with-param name="string" select="."/>
            <xsl:with-param name="search" select="'&quot;'"/>
            <xsl:with-param name="replace" select="'\&quot;'"/>
        </xsl:call-template>
        <xsl:text>");</xsl:text>
    </xsl:template>

    <!-- ========================================================= -->

    <!-- OK, all of the rules are in place.  Start driving! -->
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="mylist">
        <xsl:apply-templates select="." mode="make-comment"/>
        <xsl:apply-templates select="." mode="cpp-code"/>
    </xsl:template>

</xsl:stylesheet>



On Sat, 2005-01-08 at 14:02 -0800, J.P. wrote:
> I am trying to transform xml into c++ code. I want to put the original 
> xml source tree in c++ comments (/* ... */) so that people know where 
> the c++ code was transformed from.
> 
> For example:
> 
> //////////////// Xml ///////////////////////////////////
> <mylist>
>     <item>foo</item>
>     <item>bar</item>
> </mylist>
> 
> ///////////////// c++ code //////////////////////////////
> /*
>   Following code was created from xml source tree:
>   <mylist>
>     <item>foo</item>
>     <item>bar</item>
>   </mylist>
> */
> std::vector<std::string> mylist;
> mylist.push_back("foo");
> mylist.push_back("bar");
> 
> However there is one problem bothering me. If in the xml source tree, 
> there is any string containing substring "*/", it will break the c++ 
> comment in c++ code.
> For example:
> //////////////// Xml ///////////////////////////////////
> <mylist>
>     <item>foo</item>
>     <item>bar</item>
>     <item>item that breaks comment because of */</item>
> </mylist>
> 
> ///////////////// c++ code //////////////////////////////
> /*
>   Following code was created from xml source tree:
>   <mylist>
>     <item>foo</item>
>     <item>bar</item>
>     <item>item that breaks comment because of */</item>
>   </mylist>
> */
> std::vector<std::string> mylist;
> mylist.push_back("foo");
> mylist.push_back("bar");
> mylist.push_back("item that breaks comment because of */");
> 
> 
> Is there anyway I can recursively check all nodes in the source tree to 
> see if there is any string containing substring "*/"?


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]