Honza,

Sablotron should actually escape the HTML attributes holding URIs the
way you need. In fact, the code is ready but only used for a different
purpose. So I attach a short patch that should do the job. Apply inside
the engine subdirectory. BTW make sure your output method is html, e.g.
by including <xsl:output method="html"/> in your stylesheet.

Hope this helps,
Tom

Honza Pazdziora wrote:
> 
> Hello,
> 
> I use Sablotron via AxKit and XML::Sablotron. I try to transform input
> 
>         <people>
>                 <person><id>243</id><name>Peter Jones</name></person>
>                 <person><id>244</id><name>Carol Smith</name></person>
>         </people>
> to
>         <UL>
>         <LI><A HREF="/homepage/?id=243">Peter Jones</A>
>         <LI><A HREF="/homepage/?id=244">Carol Smith</A>
>         </UL>
> 
> This is easy in easy cases.
> 
> However, the question is: what is the recommended way of escaping
> the parameters in the URL? Here they are numbers but as they may
> contain anything in other situations, a way of changing
> 
>         <id>" val "</id>
> to
>         "?id=%22+val+%22"
> 
> would be needed. Currently (for lack of better idea) I do this by
> postprocessing the output and doing this kind of transformation in
> XPathScript but I wonder if some way of doing this directly in
> Sablotron exists or is planned.
> 
> One way I can see is xsl:eval and call either some C or (with
> XML::Sablotron) perl function or evaluation code a la JVS or ASP/VB
> approaches, another way could be using namespaces -- but I honestly
> admit that I don't know how standard compliant these would be.
> 
> Any comments would be appreciated,
> 
> --
> ------------------------------------------------------------------------
>  Honza Pazdziora | [EMAIL PROTECTED] | http://www.fi.muni.cz/~adelton/
>  .project: Perl, mod_perl, DBI, Oracle, auth. WWW servers, XML/XSL, ...
> ------------------------------------------------------------------------
Index: output.cpp
===================================================================
RCS file: d:/cvs-master/ga/src/Sablot/engine/output.cpp,v
retrieving revision 1.13
diff -a -u -r1.13 output.cpp
--- output.cpp  2000/09/13 12:04:40     1.13
+++ output.cpp  2000/12/04 21:42:54
@@ -84,6 +84,23 @@
     "input", "isindex", "link", "meta", "param", NULL
 };
 
+const char* theURI_HTMLAtts[] = 
+{
+    "action",       // FORM
+    "archive",      // OBJECT
+    "background",   // BODY
+    "cite",         // BLOCKQUOTE, Q, DEL, INS
+    "classid",      // OBJECT
+    "codebase",     // OBJECT, APPLET
+    "data",         // OBJECT
+    "href",         // A, AREA, LINK, BASE
+    "longdesc",     // IMG, FRAME, IFRAME
+    "profile",      // HEAD
+    "src",          // SCRIPT, INPUT, FRAME, IFRAME, IMG
+    "usemap",       // IMG, INPUT, OBJECT
+    NULL
+};
+
 Bool isEmptyHTMLTag(const Str& name)
 {
     int ndx = lookupNoCase(name, theEmptyHTML40Tags);
@@ -91,6 +108,15 @@
     return !!theEmptyHTML40Tags[ndx];
 }
 
+//  this should be improved by checking the name of the parent element
+//  see the element names in theURI_HTMLAtts
+Bool isURI_HTMLAtt(const Str& name)
+{
+    int ndx = lookupNoCase(name, theURI_HTMLAtts);
+    // return TRUE iff found
+    return !!theURI_HTMLAtts[ndx];
+}
+
 //
 //  OutputDefinition
 //
@@ -353,10 +379,14 @@
             E( sendStr(attQName.getPrefix()) );
             sendLit(":");
         };
-        E( sendStr(atts[i] -> key.getLocal()) );
+        const Str& localAttName = atts[i] -> key.getLocal();
+        E( sendStr(localAttName) );
         sendLit("=\"");
-        E( sendStrEsc(atts[i] -> value, 
-            method == OUTPUT_HTML ? ESCAPING_HTML_ATTR : ESCAPING_ATTR) );
+        EscMode escapingMode = 
+            (method == OUTPUT_HTML ? ESCAPING_HTML_ATTR : ESCAPING_ATTR);
+        if (method == OUTPUT_HTML && isURI_HTMLAtt(localAttName))
+            escapingMode = ESCAPING_HTML_URI;
+        E( sendStrEsc(atts[i] -> value, escapingMode));
         sendLit("\"");
     };
 

Reply via email to