Connecting Tech Pros Worldwide Help | Site Map

XSLT - Extracting name-value pairs

  #1  
Old November 7th, 2008, 04:55 PM
Ebenezer
Guest
 
Posts: n/a
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.
  #2  
Old November 7th, 2008, 05:55 PM
Martin Honnen
Guest
 
Posts: n/a

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/
  #3  
Old November 7th, 2008, 06:35 PM
Ebenezer
Guest
 
Posts: n/a

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>
>
>
  #4  
Old November 8th, 2008, 12:25 PM
Johannes Koch
Guest
 
Posts: n/a

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.)
  #5  
Old November 8th, 2008, 04:45 PM
Dimitre Novatchev
Guest
 
Posts: n/a

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


  #6  
Old November 8th, 2008, 06:15 PM
Ebenezer
Guest
 
Posts: n/a

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.
  #7  
Old November 8th, 2008, 06:15 PM
Ebenezer
Guest
 
Posts: n/a

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.
  #8  
Old November 9th, 2008, 04:05 AM
Dimitre Novatchev
Guest
 
Posts: n/a

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.


  #9  
Old November 9th, 2008, 04:05 AM
Dimitre Novatchev
Guest
 
Posts: n/a

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.


  #10  
Old November 9th, 2008, 04:05 AM
Dimitre Novatchev
Guest
 
Posts: n/a

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

  #11  
Old November 10th, 2008, 09:15 AM
Ebenezer
Guest
 
Posts: n/a

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 :)
  #12  
Old November 10th, 2008, 09:15 AM
Ebenezer
Guest
 
Posts: n/a

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
xslt: making use of edit/delete buttons is that actually work? Andy B answers 3 June 27th, 2008 08:20 PM
Help!. Conversion of XML to data objects =?Utf-8?B?Q2Fpcm4=?= answers 3 June 27th, 2008 08:20 PM
outputting Pairs of Nodes awebguynow answers 1 December 29th, 2005 11:15 PM
iTunes and XSLT Richard Rudie answers 4 July 20th, 2005 09:11 AM