Connecting Tech Pros Worldwide Forums | Help | Site Map

XSLT - Extracting name-value pairs

Ebenezer
Guest
 
Posts: n/a
#1: Nov 7 '08
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.

Martin Honnen
Guest
 
Posts: n/a
#2: Nov 7 '08

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, '&amp;')">
<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, '&amp;')"/>
</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/
Ebenezer
Guest
 
Posts: n/a
#3: Nov 7 '08

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, '&amp;')">
<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, '&amp;')"/>
</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>
>
>
Johannes Koch
Guest
 
Posts: n/a
#4: Nov 8 '08

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 '&amp;'.

--
Johannes Koch
In te domine speravi; non confundar in aeternum.
(Te Deum, 4th cent.)
Dimitre Novatchev
Guest
 
Posts: n/a
#5: Nov 8 '08

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"
Quote:
>
<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="'&amp;'"/>
</xsl:call-template>
</xsl:variable>

<xsl:for-each select=
"ext:node-set($vTokens)/word
[starts-with(.,$pMustStart)]"
Quote:
>
<xsl:variable name="vactDelim">
<xsl:if test="position() 1">&amp;</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&amp;foo=bar&amp;foo2= bar2&amp;name2=value0" />
<node
url="myotherpage.php?name4=value4&amp;foo=bar3&amp ;foo2=bar5&amp;name2=value8"
/>
</nodes>

produces the wanted results:

<nodes>
<node url="mypage.php?foo=bar&amp;foo2=bar2"/>
<node url="myotherpage.php?foo=bar3&amp;foo2=bar5"/>
</nodes>

Hope this helped.

Cheers,
Dimitre Novatchev


Ebenezer
Guest
 
Posts: n/a
#6: Nov 8 '08

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 '&amp;'.
Of course, but the parser I use won't bother on that.
Ebenezer
Guest
 
Posts: n/a
#7: Nov 8 '08

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.
Dimitre Novatchev
Guest
 
Posts: n/a
#8: Nov 9 '08

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.


Dimitre Novatchev
Guest
 
Posts: n/a
#9: Nov 9 '08

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 '&amp;'.
>
Of course, but the parser I use won't bother on that.
Then this is not a true (compliant) XML parser.


Dimitre Novatchev
Guest
 
Posts: n/a
#10: Nov 9 '08

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.
>
>

Ebenezer
Guest
 
Posts: n/a
#11: Nov 10 '08

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 '&amp;'.
>Of course, but the parser I use won't bother on that.
Then this is not a true (compliant) XML parser.
You got it :)
Ebenezer
Guest
 
Posts: n/a
#12: Nov 10 '08

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.
Closed Thread