XSLT - Extracting name-value pairs 
November 7th, 2008, 04:55 PM
| | | |
Let's suppose I have some nodes in an XML file, with an URL attribute:
<node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
<node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8" />
and so on.
Let's suppose I want to retrieve this @url parameter, BUT ONLY with the
values, in querystring, associated with "foo" and "foo2" (thus
discarding name1, name2, name4 and every other different ones).
In other words, I must obtain:
mypage.php?foo=bar&foo2=bar2
myotherpage.php?&foo=bar3&foo2=bar5
.... and so on.
Is there a convenient way, in a transformation with XSL, to obtain this
string manipulation? (I'd prefer to stick to XSLT1.0, if possible)
Thanks in advance for your help. | 
November 7th, 2008, 05:55 PM
| | | | re: XSLT - Extracting name-value pairs
Ebenezer wrote: Quote:
Let's suppose I have some nodes in an XML file, with an URL attribute:
>
<node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
<node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8" />
>
and so on.
>
Let's suppose I want to retrieve this @url parameter, BUT ONLY with the
values, in querystring, associated with "foo" and "foo2" (thus
discarding name1, name2, name4 and every other different ones).
>
In other words, I must obtain:
>
mypage.php?foo=bar&foo2=bar2
myotherpage.php?&foo=bar3&foo2=bar5
... and so on.
>
Is there a convenient way, in a transformation with XSL, to obtain this
string manipulation? (I'd prefer to stick to XSLT1.0, if possible)
| Well
substring-before(node/@url, '?')
would give you the file name, the query string would need to be parsed
which needs a recursive template or an extension function in XSLT 1.0.
In XSLT 2.0 you could use the tokenize function and/or xsl:analyze-string:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/2008/mf"
exclude-result-prefixes="xsd mf"
version="2.0">
<xsl:function name="mf:get-query" as="xsd:string">
<xsl:param name="qs" as="xsd:string"/>
<xsl:param name="params" as="xsd:string*"/>
<xsl:variable name="filtered-qs" as="xsd:string*">
<xsl:for-each select="tokenize($qs, '&')">
<xsl:analyze-string
select="."
regex="({string-join($params, '|')})=\w*">
<xsl:matching-substring>
<xsl:sequence select="regex-group(0)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="string-join($filtered-qs, '&')"/>
</xsl:function>
<xsl:template match="node">
<xsl:value-of select="concat(substring-before(@url, '?'), '?',
mf:get-query(substring-after(@url, '?'), ('foo', 'foo2')))"/>
</xsl:template>
</xsl:stylesheet>
--
Martin Honnen http://JavaScript.FAQTs.com/ | 
November 7th, 2008, 06:35 PM
| | | | re: XSLT - Extracting name-value pairs
Thanks a lot for sharing and helping, Martin, your information is so
valuable, I'll carefully study your code.
Martin Honnen ha scritto: Quote:
Ebenezer wrote: Quote:
>Let's suppose I have some nodes in an XML file, with an URL attribute:
>>
><node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
><node
>url="myotherpage.php?name4=value4&foo=bar3&foo2=b ar5&name2=value8" />
>>
>and so on.
>>
>Let's suppose I want to retrieve this @url parameter, BUT ONLY with
>the values, in querystring, associated with "foo" and "foo2" (thus
>discarding name1, name2, name4 and every other different ones).
>>
>In other words, I must obtain:
>>
>mypage.php?foo=bar&foo2=bar2
>myotherpage.php?&foo=bar3&foo2=bar5
>... and so on.
>>
>Is there a convenient way, in a transformation with XSL, to obtain
>this string manipulation? (I'd prefer to stick to XSLT1.0, if possible)
| >
Well
substring-before(node/@url, '?')
would give you the file name, the query string would need to be parsed
which needs a recursive template or an extension function in XSLT 1.0.
In XSLT 2.0 you could use the tokenize function and/or xsl:analyze-string:
>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/2008/mf"
exclude-result-prefixes="xsd mf"
version="2.0">
>
<xsl:function name="mf:get-query" as="xsd:string">
<xsl:param name="qs" as="xsd:string"/>
<xsl:param name="params" as="xsd:string*"/>
<xsl:variable name="filtered-qs" as="xsd:string*">
<xsl:for-each select="tokenize($qs, '&')">
<xsl:analyze-string
select="."
regex="({string-join($params, '|')})=\w*">
<xsl:matching-substring>
<xsl:sequence select="regex-group(0)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="string-join($filtered-qs, '&')"/>
</xsl:function>
>
<xsl:template match="node">
<xsl:value-of select="concat(substring-before(@url, '?'), '?',
mf:get-query(substring-after(@url, '?'), ('foo', 'foo2')))"/>
</xsl:template>
>
</xsl:stylesheet>
>
>
| | 
November 8th, 2008, 12:25 PM
| | | | re: XSLT - Extracting name-value pairs
Ebenezer schrieb: Quote:
Let's suppose I have some nodes in an XML file, with an URL attribute:
>
<node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
<node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8" />
| If you have this, it's not XML. Instead of '&' in the url attribute
value, write '&'.
--
Johannes Koch
In te domine speravi; non confundar in aeternum.
(Te Deum, 4th cent.) | 
November 8th, 2008, 04:45 PM
| | | | re: XSLT - Extracting name-value pairs
"Ebenezer" <vaciapairat@spam.comwrote in message
news:5j_Qk.187764$FR.474551@twister1.libero.it... Quote:
Let's suppose I have some nodes in an XML file, with an URL attribute:
>
<node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
<node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8"
/>
>
and so on.
>
Let's suppose I want to retrieve this @url parameter, BUT ONLY with the
values, in querystring, associated with "foo" and "foo2" (thus discarding
name1, name2, name4 and every other different ones).
>
In other words, I must obtain:
>
mypage.php?foo=bar&foo2=bar2
myotherpage.php?&foo=bar3&foo2=bar5
... and so on.
>
Is there a convenient way, in a transformation with XSL, to obtain this
string manipulation? (I'd prefer to stick to XSLT1.0, if possible)
>
Thanks in advance for your help.
| Using FXSL 1.x and its "str-split-to-words" template, such processing is
trivial.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext" <xsl:import href="strSplit-to-Words.xsl"/>
<!-- To be applied upon: testTokenize2.xml -->
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@url">
<xsl:attribute name="{name()}">
<xsl:variable name="vHdUrl" select=
"substring-before(.,'?')"
/>
<xsl:variable name="vTlUrl" select=
"substring-after(.,'?')"
/>
<xsl:variable name="vFilteredActions">
<xsl:call-template name="filterActions">
<xsl:with-param name="pInput" select="$vTlUrl"/>
<xsl:with-param name="pMustStart" select="'foo'"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select=
"concat($vHdUrl,'?',$vFilteredActions)"
/>
</xsl:attribute>
</xsl:template>
<xsl:template name="filterActions">
<xsl:param name="pInput"/>
<xsl:param name="pMustStart" select="'x'"/>
<xsl:variable name="vTokens">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="$pInput"/>
<xsl:with-param name="pDelimiters" select="'&'"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select=
"ext:node-set($vTokens)/word
[starts-with(.,$pMustStart)]" <xsl:variable name="vactDelim">
<xsl:if test="position() 1">&</xsl:if>
</xsl:variable>
<xsl:value-of select="concat($vactDelim, .)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when applied on this xml document:
<nodes>
<node
url="mypage.php?name1=value1&foo=bar&foo2= bar2&name2=value0" />
<node
url="myotherpage.php?name4=value4&foo=bar3& ;foo2=bar5&name2=value8"
/>
</nodes>
produces the wanted results:
<nodes>
<node url="mypage.php?foo=bar&foo2=bar2"/>
<node url="myotherpage.php?foo=bar3&foo2=bar5"/>
</nodes>
Hope this helped.
Cheers,
Dimitre Novatchev | 
November 8th, 2008, 06:15 PM
| | | | re: XSLT - Extracting name-value pairs
Johannes Koch ha scritto: Quote:
Ebenezer schrieb: Quote:
>Let's suppose I have some nodes in an XML file, with an URL attribute:
>>
><node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
><node
>url="myotherpage.php?name4=value4&foo=bar3&foo2=b ar5&name2=value8" />
| >
If you have this, it's not XML. Instead of '&' in the url attribute
value, write '&'.
| Of course, but the parser I use won't bother on that. | 
November 8th, 2008, 06:15 PM
| | | | re: XSLT - Extracting name-value pairs
Dimitre Novatchev ha scritto: Quote:
"Ebenezer" <vaciapairat@spam.comwrote in message
news:5j_Qk.187764$FR.474551@twister1.libero.it...
Using FXSL 1.x and its "str-split-to-words" template, such processing is
trivial.
| Unfortunately, I use another engine. | 
November 9th, 2008, 04:05 AM
| | | | re: XSLT - Extracting name-value pairs
"Ebenezer" <vaciapairat@spam.comwrote in message
news:AAkRk.188514$FR.475337@twister1.libero.it... Quote:
Dimitre Novatchev ha scritto: Quote:
>"Ebenezer" <vaciapairat@spam.comwrote in message
>news:5j_Qk.187764$FR.474551@twister1.libero.it. ..
>Using FXSL 1.x and its "str-split-to-words" template, such processing is
>trivial.
| >
Unfortunately, I use another engine.
| Hmm... Did I say that a specific "engine" was necessary for the solution?
FXSL 1.x works with *any* XSLT 1.0 processor that supports the
exsl:node-set() extension function.
There are 3 separate versions for MSXML, Xalan and Saxon, although the last
two XSLT 1.0 processors implement exsl:node-set().
For MSXML, there is a way to implement exslt:node-set() (and in any XSLT
processor that supports extension functions written in inline-JavaScript).
See: http://www.jenitennison.com/blog/node/24
Lastly, FXSL 2.0 is the latest (since the last 4-5 years) version of FXSL
which is written in and for XSLT 2.0. It doesn't use any extension functions
at all. | 
November 9th, 2008, 04:05 AM
| | | | re: XSLT - Extracting name-value pairs
"Ebenezer" <vaciapairat@spam.comwrote in message
news:4AkRk.188513$FR.475325@twister1.libero.it... Quote:
Johannes Koch ha scritto: Quote:
>Ebenezer schrieb: Quote:
>>Let's suppose I have some nodes in an XML file, with an URL attribute:
>>>
>><node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
>><node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8"
>>/>
| >>
>If you have this, it's not XML. Instead of '&' in the url attribute
>value, write '&'.
| >
Of course, but the parser I use won't bother on that.
| Then this is not a true (compliant) XML parser. | 
November 9th, 2008, 04:05 AM
| | | | re: XSLT - Extracting name-value pairs
>Unfortunately, I use another engine. Quote:
>
Hmm... Did I say that a specific "engine" was necessary for the solution?
>
| Or did you think that FXSL was an "engine"?
It most certainly isn't an "engine".
FXSL is a library of functions/templates, written in pure XSLT. As such, its
functions can be used under any compliant XSLT 2.0 processor or any
compliant XSLT 1.0 processor that either implements the exsl:node-set()
extension function, or is one of the following XSLT 1.0 processors: MSXML
(3,4,6), Xalan, Saxon.
Cheers,
Dimitre Novatchev
"Dimitre Novatchev" <dnovatchev@cnntp.orgwrote in message
news:49165fc4$0$17067$6e1ede2f@read.cnntp.org... Quote:
>
"Ebenezer" <vaciapairat@spam.comwrote in message
news:AAkRk.188514$FR.475337@twister1.libero.it... Quote:
>Dimitre Novatchev ha scritto: Quote:
>>"Ebenezer" <vaciapairat@spam.comwrote in message
>>news:5j_Qk.187764$FR.474551@twister1.libero.it.. .
>>Using FXSL 1.x and its "str-split-to-words" template, such processing is
>>trivial.
| >>
>Unfortunately, I use another engine.
| >
Hmm... Did I say that a specific "engine" was necessary for the solution?
>
FXSL 1.x works with *any* XSLT 1.0 processor that supports the
exsl:node-set() extension function.
>
There are 3 separate versions for MSXML, Xalan and Saxon, although the
last two XSLT 1.0 processors implement exsl:node-set().
>
For MSXML, there is a way to implement exslt:node-set() (and in any XSLT
processor that supports extension functions written in inline-JavaScript).
See:
> http://www.jenitennison.com/blog/node/24
>
Lastly, FXSL 2.0 is the latest (since the last 4-5 years) version of FXSL
which is written in and for XSLT 2.0. It doesn't use any extension
functions at all.
>
>
| | 
November 10th, 2008, 09:15 AM
| | | | re: XSLT - Extracting name-value pairs
Dimitre Novatchev ha scritto: Quote:
"Ebenezer" <vaciapairat@spam.comwrote in message
news:4AkRk.188513$FR.475325@twister1.libero.it... Quote:
>Johannes Koch ha scritto: Quote:
>>Ebenezer schrieb:
>>>Let's suppose I have some nodes in an XML file, with an URL attribute:
>>>>
>>><node url="mypage.php?name1=value1&foo=bar&foo2=bar2&nam e2=value0" />
>>><node url="myotherpage.php?name4=value4&foo=bar3&foo2=ba r5&name2=value8"
>>>/>
>>If you have this, it's not XML. Instead of '&' in the url attribute
>>value, write '&'.
| >Of course, but the parser I use won't bother on that.
| Then this is not a true (compliant) XML parser.
| You got it :) | 
November 10th, 2008, 09:15 AM
| | | | re: XSLT - Extracting name-value pairs
Dimitre Novatchev ha scritto: Quote: Quote: Quote: |
>>Unfortunately, I use another engine.
| >Hmm... Did I say that a specific "engine" was necessary for the solution?
>>
| >
Or did you think that FXSL was an "engine"?
It most certainly isn't an "engine".
FXSL is a library of functions/templates, written in pure XSLT. As such, its
functions can be used under any compliant XSLT 2.0 processor or any
compliant XSLT 1.0 processor that either implements the exsl:node-set()
extension function, or is one of the following XSLT 1.0 processors: MSXML
(3,4,6), Xalan, Saxon.
| Yes, actually I thought that it was an engine, never heard of this library.
Lot of thanks for sharing and helping, Dimitre, I'll dig into that too.
Cheers. |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,662 network members.
|