Re: [xslt] XPath string functions question.



Hi, Derek,

That works. Thanks.

That's close to, but not exactly what I want to do. You replace all "*/" 
    with "star-slash". what I want to do is:

1.If the source tree is good, copy it (using copy-of, copy, or any 
methods that do the job).
2.If the source tree or any sub-tree contains "*/", only output some 
warning message such as:
/*
  The source tree contains "*/". Can't not quote it here.
*/

Can we do that in xslt? Thanks.

Derek Poon wrote:
> 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]