Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XSLT Software Tool

102 views
Skip to first unread message

Drew

unread,
Apr 25, 2003, 5:02:26 PM4/25/03
to
I am looking for an XML/XSL software tool that will help me create an
XSLT that I can transfer an XML mapping to another XML mapping. For
instance, let's say I want the <Address> tag from XML1 to be
translated into the <BuyerAddress> tag in XML2. Thanks!

- Drew

Mike Sharp

unread,
Apr 25, 2003, 5:11:22 PM4/25/03
to
Lots of good tools out there--I'll let some of the authors in this forum
plug their own! But what you're wanting to do is rather simple, too. You
start out with an identity tranformation (the first two templates below) and
then add templates for nodes you want to change. You can change the order
of nodes, and the very structure of the document itself, but this gets a bit
trickier. But only a bit.

Regards,
Mike Sharp

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/ | node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@*">
<xsl:copy>
</xsl:copy>
</xsl:template>

<xsl:template match="Address">
<BuyerAddress>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</BuyerAddress>
</xsl:template>

</xsl:stylesheet>


"Drew" <andre...@yahoo.com> wrote in message
news:e3fb65d3.03042...@posting.google.com...

Oleg Tkachenko

unread,
Apr 26, 2003, 12:33:32 PM4/26/03
to
Drew wrote:

btw, BizTalk Mapper tool might be helpful here. It allows to map
visually two XML schema (XDR only unfortunately) and generate XSLT
stylesheet to transform one to another.

--
Oleg Tkachenko
http://www.tkachenko.com/blog
Multiconn Technologies, Israel

Chris Barber

unread,
Apr 26, 2003, 12:46:06 PM4/26/03
to
Tibco XML Transform (ooh is that expensive) shows a 'graphical' mapping of XML to XML.
Marrowsoft Xselerator is pretty good but is a 'normal' XSLT dev. environment.

Chris.

"Oleg Tkachenko" <ol...@multiconn.com> wrote in message news:uwWNdGBD...@TK2MSFTNGP12.phx.gbl...

Dimitre Novatchev

unread,
Apr 26, 2003, 1:20:36 PM4/26/03
to

"Chris Barber" <ch...@blue-canoe.net.nospam> wrote in message
news:ubIQWNBD...@TK2MSFTNGP10.phx.gbl...

> Tibco XML Transform (ooh is that expensive) shows a 'graphical' mapping of
XML to XML.
> Marrowsoft Xselerator is pretty good but is a 'normal' XSLT dev.
environment.
>

Or to put it in another way, XSelerator is for the professional XSLT
programmer.

=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL


Chris Barber

unread,
Apr 26, 2003, 4:14:04 PM4/26/03
to
Personal preferences always get a good number of responses. LoL.

I love them both (apart from my Xselerator trial period is about to run out! - better get the credit card out then and
put my money where my mouth is I suppose :))

I tried XMLSpy but could never really feel comfortable with it for some reason - that'll be the personal preferences
again :)

Turbo has it's quirks cos it's Java written but the graphical representation of the XML to XML template matches is very
useful. Xselerator is a lot better for me cos it has all the intellisense for both XSLT and HTML (which for a starting
out novice like me is essential - you get to see options that you'd never remember from reading books).

Anyway - a newsgroup is not really a good place for my thoughts so I'll stop there.

BTW: Dimitre, I can't remember if you are associated with a specific XSLT development tool? If you are then I'd love to
trial it. Unlike my VB development life - where MS and Visual Basic 6.0 was the only tool available to me - I'm trying
to get my hands on as many XML and XSLT tools as possible so I can get a better handle on which suit me (for what I'm
doing - generally XML to XML and XML to HTML).

Regards,

Chris Barber.


"Dimitre Novatchev" <dnova...@yahoo.com> wrote in message news:b8ee9r$92els$1...@ID-152440.news.dfncis.de...

Dimitre Novatchev

unread,
Apr 26, 2003, 4:57:10 PM4/26/03
to

"Chris Barber" <ch...@blue-canoe.net.nospam> wrote in message
news:%23bSFkBD...@TK2MSFTNGP11.phx.gbl...

> BTW: Dimitre, I can't remember if you are associated with a specific XSLT
development tool? If you are then I'd love to
> trial it. Unlike my VB development life - where MS and Visual Basic 6.0
was the only tool available to me - I'm trying
> to get my hands on as many XML and XSLT tools as possible so I can get a
better handle on which suit me (for what I'm
> doing - generally XML to XML and XML to HTML).

Chris,

I produced the XPath Visualizer for IE (3 years ago) and for Mozilla (6
months ago). People say it is a useful XPath learning tool. It is absolutely
free and can be obtained at:

http://www.topxml.com/xpathvisualizer/default.asp (for IE)

http://www.topxml.com/code/default.asp?p=3&id=v20021221025528&ms=30&l=&sw=All
(for Mozilla)


However, I consider as my personal achievement the implementation in XSLT of
a number of some of the most basic functional programming design patterns
(e.g. higher-order functions, partial application, folding (primitive
recursion) over node-sets and strings, etc.). This is what the FXSL
functional programming library for XSLT offer. The project page for FXSL
is:

https://sourceforge.net/projects/fxsl/

Some detailed materials explaining these basic FP design patterns and their
concrete implementation and use are contained on the FXSL home page:

http://fxsl.sourceforge.net


I hope these fit at least partially what you're looking for.

Chris Barber

unread,
Apr 26, 2003, 7:41:43 PM4/26/03
to
I can't believe that I missed the XPath visualiser in my search for XML tools. It looks excellent and I suspect will
have pride of place in my toolset. I can't count the number of times I've banged my head on the desk trying to find out
why an XPath won't give me what I want.

I got hold of the FXSL download but I'm a bit stumped as to what I'm supposed to do with it? There appears to be a
library of XML and XSL documents but I can;t find any significant documentation on what or how they can be applied?

Thanks,

Chris.

"Dimitre Novatchev" <dnova...@yahoo.com> wrote in message news:b8eqvt$8phdl$1...@ID-152440.news.dfncis.de...

Dimitre Novatchev

unread,
Apr 27, 2003, 1:57:49 AM4/27/03
to

"Chris Barber" <ch...@blue-canoe.net.nospam> wrote in message
news:e99Dm1ED...@TK2MSFTNGP11.phx.gbl...

> I can't believe that I missed the XPath visualiser in my search for XML
tools. It looks excellent and I suspect will
> have pride of place in my toolset. I can't count the number of times I've
banged my head on the desk trying to find out
> why an XPath won't give me what I want.
>
> I got hold of the FXSL download but I'm a bit stumped as to what I'm
supposed to do with it? There appears to be a
> library of XML and XSL documents but I can;t find any significant
documentation on what or how they can be applied?
>

Just start reading the materials on http://fxsl.sf.net

Start with this one:

http://fxsl.sourceforge.net/articles/FuncProg/Functional%20Programming.html

You will find very detailed explanations and many examples.

Chris Barber

unread,
Apr 27, 2003, 6:04:35 AM4/27/03
to
I started reading this morning.
Whoo - that's a bit above my current level at the moment but I can see where you're going with it.
No doubt I'll come back to it in more detail when I've finished my current contract.

Thanks.

Chris.

"Dimitre Novatchev" <dnova...@yahoo.com> wrote in message news:b8fqlj$98cck$1...@ID-152440.news.dfncis.de...

Dimitre Novatchev

unread,
Apr 27, 2003, 6:27:04 AM4/27/03
to

"Chris Barber" <ch...@blue-canoe.net.nospam> wrote in message
news:OEiCpRKD...@TK2MSFTNGP10.phx.gbl...

> I started reading this morning.
> Whoo - that's a bit above my current level at the moment but I can see
where you're going with it.
> No doubt I'll come back to it in more detail when I've finished my current
contract.
>
> Thanks.
>
> Chris.

In a few simple words -- FXSL is a functional programming library for XSLT.
It can be a powerful tool for XSLT programming, which increases programmer
efficiency by providing support for much higher level of software
abstraction, encapsulation and re-use.

Problems that have traditionally been considered "difficult or impossible"
to solve with XSLT (e.g. text processing, complicated numerical methods,
combinatorial algorithms) are quite straightforward solved with XSLT.

Mark Johnson

unread,
Apr 29, 2003, 6:49:05 AM4/29/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>Just start reading the materials on http://fxsl.sf.net

>http://fxsl.sourceforge.net/articles/FuncProg/Functional%20Programming.html

>You will find very detailed explanations and many examples.

Unfortunately, the explanations are lacking. It's a language without
definition - the 'made-up' words of Lewis Carroll.

For ex:

The function sum that computes the sum of the elements of a list can
be defined as follows:

sum [] = 0

sum (n:ns) = n + sum ns


I'm guessing it would seem extremely tedious, and almost pointless, to
explain the notation and the ideas and wording behind it? CS101
somewhere, instead?

Or CS301 for ex:

http://undergraduate.cs.uwa.edu.au/courses/230.301/lectureNotes/22/23.pdf

Dimitre Novatchev

unread,
Apr 29, 2003, 2:15:17 PM4/29/03
to

"Mark Johnson" <1023...@compuserve.com> wrote in message
news:h4msavo7d29a59277...@4ax.com...

> "Dimitre Novatchev" <dnova...@yahoo.com> wrote:
>
> >Just start reading the materials on http://fxsl.sf.net
>
>
>http://fxsl.sourceforge.net/articles/FuncProg/Functional%20Programming.html
>
> >You will find very detailed explanations and many examples.
>
> Unfortunately, the explanations are lacking. It's a language without
> definition - the 'made-up' words of Lewis Carroll.
>

No, it is said that this is how one would write it in *Haskell*. And there's
a link to the Haskell home page, a Haskell tutorial and a book on Haskell.

> I'm guessing it would seem extremely tedious, and almost pointless, to
> explain the notation and the ideas and wording behind it?

This is not a course in computer science. And part of the value is exactly
in the fact that not everything will be completely understood by everybody
on the first reading. Without a challenge this page would be of no value to
anyone.


This page has been accesed many thousands times and I'm glad now we have the
first remark that it is not completely understandable.

Mark Johnson

unread,
Apr 29, 2003, 4:40:13 PM4/29/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>This is not a course in computer science. And part of the value is exactly
>in the fact that not everything will be completely understood by everybody
>on the first reading. Without a challenge this page would be of no value to
>anyone.

>This page has been accesed many thousands times and I'm glad now we have the
>first remark that it is not completely understandable.

Glad I could be of service. It is a lot to read, those page 11 links.
But I'm sure it would answer the questions about the notation, etc.

I hope it isn't lost that xslt is not only useful, but pretty darned
easy to learn. I came across it less than a week ago. And I was able
to create a 'template', in that time, that probably did in a
relatively few lines - with long tags, admittedly - what I might still
be working on with vb, and recordsets and joins, filtering, sorting,
and so on. This xslt is, by design, literally template based. As a way
to transform a raw database into an html page, it's a wonder more
people aren't talking about this. As I wrote when I first found this
ng, it's pretty quiet compared to other ngs, or at least it is on the
servers I used to read the messages.

I would add, too, that without the xsl:script or msxsl:script feature,
it would be near impossible to get certain things done. It's sort of
the equivalent of plug-in filters for a graphics programs. I notice
the fxsl uses no xsl:script?

Dimitre Novatchev

unread,
Apr 29, 2003, 5:24:19 PM4/29/03
to

"Mark Johnson" <1023...@compuserve.com> wrote in message
news:79otavkpvsvn4iuks...@4ax.com...

> I would add, too, that without the xsl:script or msxsl:script feature,
> it would be near impossible to get certain things done. It's sort of
> the equivalent of plug-in filters for a graphics programs.

It has been proven that XSLT is a Turing-complete language. This means that
it is in the group of the most powerful languages and if a problem can be
solved in any other language, it can be solved in XSLT, too (if all
necessary inputs can be provided).

User-written extension functions are rarely necessary. They can be harmful
in the cases when an extension function has side effects. This is why using
extension functions is not recommended in the general case.

On the other side, using extension functions with no side effects is
harmless, its only drawback being that it defeats the portability of the
xslt code.

> I notice the fxsl uses no xsl:script?

Right. FXSL is pure XSLT 1.0 (with the notable exception of the
xxx:node-set() function) and wil be 100% pure in XSLT 2.0.

Mark Johnson

unread,
Apr 29, 2003, 7:49:10 PM4/29/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>"Mark Johnson" <1023...@compuserve.com> wrote in message
>news:79otavkpvsvn4iuks...@4ax.com...

>It has been proven that XSLT is a Turing-complete language. This means that


>it is in the group of the most powerful languages and if a problem can be
>solved in any other language, it can be solved in XSLT, too (if all
>necessary inputs can be provided).

Just as example, here's the last thing I needed to add to my template.
I was just going to copy over and translate into either vbscript or
jscript (I don't think msxml3 supports javascript - it crashed when I
tried "alert()"). Could this really be performed using just xslt?

Maybe not the cleanest code. But it basically works. Lots of clumsy
string handling and RegExp calls.

' Given a relative path - e.g. "../../img/x.gif" - find the new relative path if image, or whatever, isn't moved.
' From the source template, replace all instances in the target file so it will work at the target location.

' Assumption, here, is that the target and source paths are just directories, and don't include a trailing file name.
' However, if a period/dot is found following the last slash, then everything after the last slash is trimmed from the path.
' The optional ignoreTrim flag can be set to true to prevent this.

Public Function fGetRelURL(ByVal strFullTargetPath As String, ByVal strFullSourcePath As String, _
Optional ByVal strRelPath As String, Optional ysnIgnoreTrim As Boolean)

' offs looks ahead, and the latch holds the previous offset
Dim offs, offsLatch, dum
Dim strDotPath As String, strMidPath As String, strCheck As String
Dim regExp2 As New RegExp

regExp2.Global = True
' Backslash is special reg expr char, so double up.
' The loops below assume only forward slashes are used. Make the change here.
regExp2.Pattern = "\\"
strRelPath = regExp2.replace(strRelPath, "/")
strFullTargetPath = regExp2.replace(strFullTargetPath, "/")
strFullSourcePath = regExp2.replace(strFullSourcePath, "/")

If Not ysnIgnoreTrim Then
' Save first to variable, because the arg to fStripRightDir is changed.
strCheck = strFullTargetPath
If InStr(fStripRightDir(strCheck), ".") Then strFullTargetPath = strCheck
strCheck = strFullSourcePath
If InStr(fStripRightDir(strCheck), ".") Then strFullSourcePath = strCheck
End If

' kill all leading slashes or dots
regExp2.Pattern = "^/+"
strRelPath = regExp2.replace(strRelPath, "")
If Left(strRelPath, 2) = "./" Then strRelPath = Mid(strRelPath, 3)

offs = 1
offsLatch = 1
Do While offs < Len(strFullTargetPath)
' look ahead
offs = InStr(offs, strFullTargetPath, "/")
If offs < 1 Then
Exit Do
Else
If Left(strFullTargetPath, offs) <> Left(strFullSourcePath, offs) Then
Exit Do
End If
End If
offsLatch = offs
offs = offs + 1
Loop

If Len(strFullSourcePath) > 0 Then
strMidPath = Right(strFullSourcePath, Len(strFullSourcePath) - offsLatch)
End If

If offsLatch < Len(strFullTargetPath) Then
strDotPath = Right(strFullTargetPath, Len(strFullTargetPath) - offsLatch)
regExp2.Pattern = "[^/]*/"
strDotPath = regExp2.replace(strDotPath, "../")
End If

Do
If Left(strRelPath, 3) = "../" Then
strRelPath = Right(strRelPath, Len(strRelPath) - 3)
strDotPath = "../" & strDotPath
dum = fStripRightDir(strMidPath)
Else
Exit Do
End If
Loop

fGetRelURL = "./" & strDotPath & strMidPath & strRelPath

End Function

Mark Johnson

unread,
Apr 29, 2003, 8:06:48 PM4/29/03
to
Mark Johnson <1023...@compuserve.com> wrote:

>"Dimitre Novatchev" <dnova...@yahoo.com> wrote:
>
>>"Mark Johnson" <1023...@compuserve.com> wrote in message
>>news:79otavkpvsvn4iuks...@4ax.com...
>
>>It has been proven that XSLT is a Turing-complete language. This means that
>>it is in the group of the most powerful languages and if a problem can be
>>solved in any other language, it can be solved in XSLT, too (if all
>>necessary inputs can be provided).
>
>Just as example, here's the last thing I needed to add to my template.
> I was just going to copy over and translate into either vbscript or
> jscript (I don't think msxml3 supports javascript - it crashed when I
> tried "alert()"). Could this really be performed using just xslt?


Probably should have included the following, to avoid confusion:

My mistake.


' Strip everything from strPath following the last forward or
' back slash, including the slash.
' This will strip a trailing slash, and if there are none remaining,
' it wil set strPath to ""

' The ByRef strPath is modified on exit, to the path without the
' last file or string (anything past the last slash).
' But the function returns that bit which was sliced off.

Public Function fStripRightDir(strPath As String)
Dim offs, strCh As String, strWork As String
Dim regExp1 As New RegExp

' Change backslashes to forward slashes, to remove extra tests
' But don't change strPath, itself, in this way.
strWork = strPath
regExp1.Global = True
' backslash is special reg expr char, so double up
regExp1.Pattern = "\\"
strWork = regExp1.replace(strWork, "/")

If Right(strWork, 1) = "/" Then strWork = Left(strWork,
Len(strWork) - 1)
If InStr(strWork, "/") < 1 Then
strPath = ""
fStripRightDir = ""
Exit Function
End If

offs = Len(strWork) + 1
Do While offs > 0
offs = offs - 1
If Mid(strWork, offs, 1) = "/" Then Exit Do
Loop
strPath = Left(strPath, offs)

fStripRightDir = Right(strWork, Len(strWork) - offs)

End Function

Mike Sharp

unread,
Apr 29, 2003, 8:23:48 PM4/29/03
to
MSXML 3 supports JScript just fine...but the context of an alert() isn't
supported...there's no ui to provide an alert in. It's like putting an
alert() on an ASP page in server code...no can do.

As far as the rest, I think it could indeed be done more easily in XSLT.
The translate() function will easily change backslashes to forward slashes.
But, if you're going to do complicated string manipulation, you can justify
using msxsl:script, as long as you don't create side effects. I'm sure
Dimitre will come up with a pure XSLT solution that will, as usual, make my
jaw drop! ;^)

Regards,
Mike Sharp

"Mark Johnson" <1023...@compuserve.com> wrote in message

news:rp4uavki45pdpc7ma...@4ax.com...

Mark Johnson

unread,
Apr 29, 2003, 8:49:16 PM4/29/03
to
"Mike Sharp" <rdc...@hotmail.com> wrote:

>As far as the rest, I think it could indeed be done more easily in XSLT.
>The translate() function will easily change backslashes to forward slashes.
>But, if you're going to do complicated string manipulation, you can justify
>using msxsl:script, as long as you don't create side effects. I'm sure
>Dimitre will come up with a pure XSLT solution that will, as usual, make my
>jaw drop! ;^)

So the translate can substitute for most simple RegExp? There's the
all characters after, whitespace, and so. But I'll read on translate
and see what it can do.

Still, you'd have all the variables, substring manipulation - messy as
it is (and I don't imply that this is the best or optimized algorithm,
just one that sort of works, is all). And then you have all the built
in object calls. Could that be done in an xsl tag?

Obviously, _I_ don't know. But reading xslt stuff on the web, you
don't get the sense of any of that.

Arjun Ray

unread,
Apr 29, 2003, 9:19:28 PM4/29/03
to
In <b8meko$bcsa1$1...@ID-152440.news.dfncis.de>, "Dimitre Novatchev"
<dnova...@yahoo.com> wrote:

| This page has been accesed many thousands times and I'm glad now we have
| the first remark that it is not completely understandable.

I, however, found them just about unreadable. Tag syntax is bad enough
as it is, but the padding of syntactic attribute values with leading and
trailing white space (including newlines) made it all the worse.

Dimitre Novatchev

unread,
Apr 30, 2003, 1:12:53 AM4/30/03
to

"Arjun Ray" <ar...@nmds.com.invalid> wrote in message
news:9c1uavkuakh269so0...@4ax.com...

You are again the first to say so -- many people actually have praised
highly the presentation of the code, calling it "extremely cool".

Let me guess -- is your browser Netscape 3 or older?

Arjun Ray

unread,
Apr 30, 2003, 1:49:17 AM4/30/03
to
In <b8nl58$bcun5$1...@ID-152440.news.dfncis.de>, "Dimitre Novatchev"
<dnova...@yahoo.com> wrote:

| many people actually have praised highly the presentation of the code,
| calling it "extremely cool".

I hope you at least used a program to generate such extreme coolness,
rather than create such hostile markup by hand.


| Let me guess -- is your browser Netscape 3 or older?

It isn't Netscape, and it's newer. The extreme coolness was lost to me
because I configure my browser to ignore <FONT>. Toggling stylesheets
got rid of the extraneous newlines, though.

(You do realize, I hope, that <XMP> was deprecated eons ago? I think
you wanted <TT>, but that's just a detail.)

Reverting to the subject matter, however: once I got past the formatting
I found the material quite fascinating.

Dimitre Novatchev

unread,
Apr 30, 2003, 2:28:06 PM4/30/03
to

"Arjun Ray" <ar...@nmds.com.invalid> wrote in message
news:kunuavgmksijvtdk9...@4ax.com...

> In <b8nl58$bcun5$1...@ID-152440.news.dfncis.de>, "Dimitre Novatchev"
> <dnova...@yahoo.com> wrote:
>
> | many people actually have praised highly the presentation of the code,
> | calling it "extremely cool".
>
> I hope you at least used a program to generate such extreme coolness,
> rather than create such hostile markup by hand.

No, not by hand -- this is what XSelerator's display looks like.

> Reverting to the subject matter, however: once I got past the formatting
> I found the material quite fascinating.

Thanks for this appreciation.

Dimitre Novatchev

unread,
Apr 30, 2003, 4:01:56 PM4/30/03
to
Most probably there is an XSLT solution.

However, I don't understand the problem at all.

Could you, please, specify:

1. The input (e.g. two concrete filepaths)

2. What is the desired output -- again a concrete result that must be
obtained

3. What the transformation must do -- some general desired properties, so
that the transformation will do the same good job on other inputs.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

"Mark Johnson" <1023...@compuserve.com> wrote in message
news:i63uavg9uf24pum3n...@4ax.com...

Mark Johnson

unread,
Apr 30, 2003, 4:36:48 PM4/30/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>Most probably there is an XSLT solution.
>
>However, I don't understand the problem at all.
>
>Could you, please, specify:
>
>1. The input (e.g. two concrete filepaths)

On a file server, in this case, but could be any path. So the drive,
path, but also with a possible filename at the end which has to go.

So you know the full path of the template file. You know what is going
to be the path for the output/target file. And you have the relative
path in the template, that has to be modified, and the new path used
in that same place, in the target.


>2. What is the desired output -- again a concrete result that must be
>obtained

As described there, it's thought of as a template; an HTML doc with
'holes', asp/cgi calls, to fill in those sections with strings and
other HTML tags. The template might have some relative paths to images
or HD links, buttons, boilerplate, and so on. But the template can be
applied to any directory on disk. The new file, based on the template,
would not duplicate these images or links, but refer to them where
they are. So the source, template, paths would have to be modified to
reflect the new target position. That would be the 'direction' in
which it works.


Dimitre Novatchev

unread,
Apr 30, 2003, 5:18:48 PM4/30/03
to
You didn't provide any useful info.

Please:

1. give an exact string -- e.g. "c:/xxx/yyy/zzz/ttt.html -- this is the
current file-path
2. give another exact string -- e.g. d:/aaa/bbb/ccc -- this is the
desired new file path

You have not given *any* concrete example!!!

How can you expect that someone will help? What you described until now is
not understandable at all.


"Mark Johnson" <1023...@compuserve.com> wrote in message

news:5ec0bvgsncbj1v5pa...@4ax.com...

Mark Johnson

unread,
Apr 30, 2003, 5:43:57 PM4/30/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>You didn't provide any useful info.

>Please:

>1. give an exact string -- e.g. "c:/xxx/yyy/zzz/ttt.html -- this is the
>current file-path
>2. give another exact string -- e.g. d:/aaa/bbb/ccc -- this is the
>desired new file path

>You have not given *any* concrete example!!!

Sorry.

Source, as you say above, c:/x/t/z/ or c:/x/t/z/abc.gif

Target, c:/x/t/z/a/ or c:/x/ or e: or f:/a/b/

String to modify, ../../img/one.jpg, or ./img/one/two.gif, or /ate.gif

In the procedure I posted, it takes a full path for the source, full
path for target, and the relative path to modify (along with that one
override flag).


Example:

So "../../img/one.jpg",
found in a html 'template' file at, "c:/x/t/u/tmp1.htm"
(which refers, i.e., to "one.jpg" at "c:/x/img/one.jpg")
is going to be copied and modified for a target file at,
"c:/x/place/targ.htm", based on the tmp1 'template'.

That means this string,
"../../img/one.jpg",
found in, "c:/x/t/u/tmp1.htm"
must be changed to,
"../img/one.jpg", when copied to targ.htm.

So the procedure just basically turns,
"../../img/one.jpg", the string,
into the string,
"../img/one.jpg", in this case.


In my routine, all the relative strings are isolated in a table, and
the routine which called the one that I posted is reading from that
table. But in xslt, I would think the string, itself, would be passed
to a routine.


Some input conditions:

1) the slashes could be forward or back, or mixed.
I converted all to forward, to avoid extra testing.

2) The relative path which is to be modified might be prefixed with
"./" or assorted "///", "/", etc., which I remove.

3) perhaps either of the source or target might also have a filename
attached, which I remove (though not to modify by reference that which
was passed-in). The assumption, however, is that a filename is
indicated by a dot, period, somewhere in the substring, in the
filename. And not all files have an extension. Without one, it's
treated as a directory name. Would be up to calling routine to handle
that.


Mark Johnson

unread,
Apr 30, 2003, 5:48:43 PM4/30/03
to
Mark Johnson <1023...@compuserve.com> wrote:

>>You have not given *any* concrete example!!!

>Sorry.

Sorry, again. Forgot the xml.

The target and source paths would be the same for the whole xml file.

So I could see

<project>
<fullsrcpath>....
<fulltargpath>....
</project>

And these could be then referred to when a specific path is up for
modification.

Dimitre Novatchev

unread,
May 2, 2003, 4:28:51 PM5/2/03
to

"Mark Johnson" <1023...@compuserve.com> wrote in message
news:f6f0bvc0f0i9hnvm1...@4ax.com...

> Source, as you say above, c:/x/t/z/ or c:/x/t/z/abc.gif
>
> Target, c:/x/t/z/a/ or c:/x/ or e: or f:/a/b/
>
> String to modify, ../../img/one.jpg, or ./img/one/two.gif, or /ate.gif
>
> In the procedure I posted, it takes a full path for the source, full
> path for target, and the relative path to modify (along with that one
> override flag).
>
>
> Example:
>
> So "../../img/one.jpg",
> found in a html 'template' file at, "c:/x/t/u/tmp1.htm"
> (which refers, i.e., to "one.jpg" at "c:/x/img/one.jpg")
> is going to be copied and modified for a target file at,
> "c:/x/place/targ.htm", based on the tmp1 'template'.
>
> That means this string,
> "../../img/one.jpg",
> found in, "c:/x/t/u/tmp1.htm"
> must be changed to,
> "../img/one.jpg", when copied to targ.htm.


Hi Mark,

Using FXSL one would write something like this:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:mySelect="f:mySelectLoc"
exclude-result-prefixes="msxsl mySelect"
>
<xsl:import href="..\Generic\FP\Fxsl\Msxsl\strSplit-to-Words.xsl"/>
<xsl:import href="..\Generic\FP\Fxsl\Msxsl\dropWhile.xsl"/>

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
<xsl:variable name="vrtfAbsPath">
<xsl:call-template name="getAbsPath">
<xsl:with-param name="pPath" select="/*/app/@path"/>
<xsl:with-param name="pRef" select="/*/app/fileRef"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="vAbsPath"
select="msxsl:node-set($vrtfAbsPath)/*"/>

<xsl:variable name="vrtfNewPath">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="/*/app/@newpath"/>
<xsl:with-param name="pDelimiters" select="'/\'"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="vNewPath"
select="msxsl:node-set($vrtfNewPath)/*"/>

<xsl:choose>
<xsl:when test="not($vAbsPath[1] = $vNewPath[1])">
<xsl:call-template name="genRelPath">
<xsl:with-param name="pLocations" select="$vAbsPath"/>
<xsl:with-param name="pStartingSame" select="0"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vFunSelect"
select="document('')/*/mySelect:*[1]"/>
<xsl:variable name="vrtfAbsTail">
<xsl:call-template name="dropWhile">
<xsl:with-param name="pList" select="$vAbsPath[position() >
1]"/>
<xsl:with-param name="pController" select="$vFunSelect"/>
<xsl:with-param name="pContollerParam"
select="$vNewPath[position() > 1]"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="vcntLeadingSameLocs"
select="count($vAbsPath)
-
count(msxsl:node-set($vrtfAbsTail)/*)
- 1 "/>
<xsl:call-template name="genRelPath">
<xsl:with-param name="pLocations"
select="$vAbsPath[position() > 1]"/>
<xsl:with-param name="pStartingSame"
select="$vcntLeadingSameLocs"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="genRelPath">
<xsl:param name="pLocations" select="/.."/>
<xsl:param name="pStartingSame"/>

<xsl:for-each select="$pLocations
[position() &lt;= $pStartingSame]">
<xsl:text>../</xsl:text>
</xsl:for-each>

<xsl:for-each select="$pLocations
[position() > $pStartingSame]">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">/</xsl:if>
</xsl:for-each>


</xsl:template>

<mySelect:mySelect/>
<xsl:template match="mySelect:*">
<xsl:param name="pList" select="/.."/> <!-- current lidt-node -->
<xsl:param name="pParams" select="/.."/><!-- The second list -->
<xsl:variable name="vPos"
select="count($pList/preceding-sibling::*)"/>

<xsl:if test="$pList = $pParams[position() = $vPos]">1</xsl:if>
</xsl:template>

<xsl:template name="getAbsPath">
<xsl:param name="pPath"/>
<xsl:param name="pRef"/>

<xsl:variable name="vrtfPathParts">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="$pPath"/>
<xsl:with-param name="pDelimiters" select="'/\'"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="vPathParts"
select="msxsl:node-set($vrtfPathParts)/word"/>

<xsl:variable name="vrtfRefParts">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="$pRef"/>
<xsl:with-param name="pDelimiters" select="'/\'"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="vRefParts"
select="msxsl:node-set($vrtfRefParts)/word"/>

<xsl:variable name="vpathAbsParts"
select="$vPathParts
[position()
&lt;
last() - count($vRefParts[. = '..'])]"/>

<xsl:variable name="vrefAbsParts"
select="$vRefParts[not(. = '..')]"/>

<xsl:copy-of select="$vpathAbsParts"/>
<xsl:copy-of select="$vrefAbsParts"/>
</xsl:template>
</xsl:stylesheet>


When applied on this source.xml:

<reloc>
<app path="c:/x/t/u/tmp1.htm"
newpath="c:/x/place/targ.htm"
>
<fileRef>../../img/one.jpg</fileRef>
</app>
</reloc>

the wanted result is produced:

../img/one.jpg


First I am generating a node-set, consisting of all tokens (location steps)
that the absolute file-path must have. It looks like this:

<word>c:</word>
<word>x</word>
<word>img</word>
<word>one.jpg</word>

Then I'm splitting into separate tokens (location paths) the new file-path.
It looks like:

<word>c:</word>
<word>x</word>
<word>place</word>
<word>targ.htm</word>

To do this I'm using the FXSL template "str-split-to-words", which produces
a list of tokens in the above form, given a string and a list of possible
delimiters.

Then I'm using the FXSL template "dropWhile", passing to it the list of
locations of the abs.path, the list of locations of the new-path and a
function (actually a reference to a template) that controls until when to
drop elements from the first list.

The result is a tail of the abs.list, consisting of locations that must be
added at the end of the new relative path.

Finally, the template "genRelPath" takes a list of nodes (node-set)
"pLocations" and a number "pStartingSame" . It outputs "../" pStartingSame
number of times, then the rest of the nodes in "pLocations".

I hope this illustrates well the power of using FXSL. Solving this problem
took me 20-30 minutes.

Mark Johnson

unread,
May 6, 2003, 6:11:31 PM5/6/03
to
"Dimitre Novatchev" <dnova...@yahoo.com> wrote:

>"Mark Johnson" <1023...@compuserve.com> wrote in message
>news:f6f0bvc0f0i9hnvm1...@4ax.com...

>> So "../../img/one.jpg",


>> found in a html 'template' file at, "c:/x/t/u/tmp1.htm"
>> (which refers, i.e., to "one.jpg" at "c:/x/img/one.jpg")
>> is going to be copied and modified for a target file at,
>> "c:/x/place/targ.htm", based on the tmp1 'template'.

>> That means this string,
>> "../../img/one.jpg",
>> found in, "c:/x/t/u/tmp1.htm"
>> must be changed to,
>> "../img/one.jpg", when copied to targ.htm.

>Hi Mark,

>Using FXSL one would write something like this:

. . .

>I hope this illustrates well the power of using FXSL. Solving this problem
>took me 20-30 minutes.

It does. This xslt is making a little more sense to me, as well -
though I can't say I can really speak on it, or understand it. It's
not necessarily more complicated, either, than the vb code I came up
with. But I did leave off all the input filtering stuff, which I don't
think I included there. The procedure I posted, previously, like the
one you posted, only solved the problem for a certain limited subset.
This is what I found for a more general solution to the problem:

.xml file:

<root>
<file>
<sourcepath>c:/x/y/r/h</sourcepath>
<targetpath>c:/x/y/w/t/</targetpath>
</file>

And I had wanted to just do a curdir or the like, so I wouldn't need
sourcepath. But I couldn't find any vbscript thing that would work,
not with fso or anything (not an xslt problem - but just btw). So I
have the db send the sourcepath as it creates the xml file.


called in .xsl:

select="ns:fGetRelURL(//file/*,"../common/img/b.gif"/>


And which, of course, produces: ../../r/common/img/b.gif


and in the .xsl, as a msxml:script, vbscript:

Function fGetRelURL(paths,strRelPath)

Dim offs, strDotPath, strMidPath, strCheck
Dim strFullSourcePath, strFullTargetPath, strOut
Dim regExp2
Set regExp2 = New RegExp

strFullSourcePath = paths.item(0).text
strFullTargetPath = paths.item(1).text


Btw, I never did figure how to pass a nodeset that would use the
selectsinglenode property, or even getelementsbytagname. I see this
example in a bunch of messages to these xml groups. But I couldn't get
it to work. I speculated it was sending the wrong sort of object, that
didn't have either as a method. But getelements is a common method. So
it should show up. I shouldn't get an object doesn't support, error.


' all the input preparation/'massaging'/'conditioning', etc
regExp2.Global = True


regExp2.Pattern = "\\"
strRelPath = regExp2.replace(strRelPath, "/")
strFullTargetPath = regExp2.replace(strFullTargetPath, "/")
strFullSourcePath = regExp2.replace(strFullSourcePath, "/")

strCheck = strFullTargetPath
If InStr(fStripRightDir(strCheck), ".") Then strFullTargetPath =
strCheck

sAppendIfNeeded strFullTargetPath, "/"


strCheck = strFullSourcePath
If InStr(fStripRightDir(strCheck), ".") Then strFullSourcePath =
strCheck

regExp2.Pattern = "^/+"
strRelPath = regExp2.replace(strRelPath, "")
If Left(strRelPath, 2) = "./" Then strRelPath = Mid(strRelPath, 3)

sAdjustRelPaths strFullSourcePath, strRelPath
sAppendIfNeeded strFullSourcePath, "/"
' end input preparation


offs = fUptoWhereStringsSame(strFullTargetPath, strFullSourcePath)

If offs < 1 Then
strOut = strFullTargetPath & strRelPath
Else
regExp2.Pattern = "[^/]*/"
strMidPath = Right(strFullTargetPath, Len(strFullTargetPath) -
offs)
strDotPath = regExp2.replace(strMidPath, "../")


strMidPath = Right(strFullSourcePath, Len(strFullSourcePath) -

offs)
strOut = "./" & strDotPath & strMidPath & strRelPath
End If

fGetRelURL = strOut

End Function


' removes everything right of last slash or forward slash
' changes strPath byref, but returns the bit trimmed off

Function fStripRightDir(strPath)
Dim offs, strCh, strWork
Dim regExp1
Set regExp1 = New RegExp



strWork = strPath
regExp1.Global = True

regExp1.Pattern = "\\"
strWork = regExp1.replace(strWork, "/")

If Right(strWork, 1) = "/" Then strWork = Left(strWork,
Len(strWork) - 1)
If InStr(strWork, "/") < 1 Then
strPath = ""
fStripRightDir = ""
Exit Function
End If

offs = Len(strWork) + 1
Do While offs > 0
offs = offs - 1
If Mid(strWork, offs, 1) = "/" Then Exit Do
Loop
strPath = Left(strPath, offs)

fStripRightDir = Right(strWork, Len(strWork) - offs)

End Function


Public Sub sAppendIfNeeded(strMod, strChar)

If Right(strMod, 1) <> strChar Then strMod = strMod & strChar

End Sub


' Slide the relpath 'over', as it were, removing "../" and trimming
' source/strRemoveRight, accordingly.

Public Sub sAdjustRelPaths(strRemoveRight, strRemoveLeft)
Dim dum

Do
If Left(strRemoveLeft, 3) = "../" Then
dum = fStripRightDir(strRemoveRight)
strRemoveLeft = Right(strRemoveLeft, Len(strRemoveLeft) -
3)


Else
Exit Do
End If
Loop

End Sub


' find the offs where str1 and str2 are no longer the same, reading
from left

Public Function fUptoWhereStringsSame(ByVal str1, ByVal str2)
Dim intCheck, ysnStr1Bigger, offs, i

' try and all at once check, at first
ysnStr1Bigger = Len(str1) > Len(str2)
intCheck = IIf(ysnStr1Bigger, InStr(str1, str2), InStr(str2,
str1))

If intCheck < 1 Then
If ysnStr1Bigger Then SwapIt str1, str2

For i = 1 To Len(str2)
If Mid(str1, i, 1) <> Mid(str2, i, 1) Then Exit For
Next
offs = i - 1

Else
offs = IIf(ysnStr1Bigger, Len(str2), Len(str1))
End If

fUptoWhereStringsSame = offs

End Function


Public Sub SwapIt(str1, str2)
Dim str3

str3 = str1
str1 = str2
str2 = str3

End Sub


And also an IIf, because vbscript doesn't have one.

I wondered if just putting Swapit, or the append, or very simple
functions like than in xslt might not be a good thing. I also had a
couple of dfield type procedures. But I thought just scanning
character by character would be simpler (but perhaps not if in xslt,
as you showed).

After having broken out the simpler stuff into separate routines, it
helped clarify the problem, for me. It seems more intuitive, and
easier to follow, as well. But for that advantage in the vb, I wonder
if it would necessarily be more complicated in xslt? especially for
the use of RegExp in this. But I see how you got around that in the
specifics, with that nodeset of 'tokens', and so on - + translate,
etc.

Might there be points where this 'declarative' language would
duplicate the procedural? For ex, the append is a substring test. That
would probably be just a test= is xslt, as well, correct? I would
assume the swap would be pretty easy, on 'built-in' in some way. And
so on. But anytime you're running a list (the above is almost a 'tape'
in the uptowhere comparison), it has to be 'tokenized'; has to be
transformed into nodes? And that would seem, to me, to be a little
different. On the other hand, maybe the reladjust would be, again,
just some substring manipulations, without having to break the
components into nodes?


0 new messages