473,231 Members | 1,929 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,231 software developers and data experts.

create xslt stylesheet in code

Hi,
As a follow on from an earlier post I have another question about
xslt.
Is it possible to create the stylsheet programatically? Is this
sensible? In the first phase I needed to map element name from inbound
xml to my internal elements to standardize disparate input.
Now I could just create an xslt stylesheet for each possible inbound
format and be done, but I think it would be powerful to be able store
this mapping in a database and programatically create the stylsheet.
This way I don't have to maintain potentially a great number of
stylesheets. The trouble is, I can't find any example where the
stylesheet is not Load'ed from a file.

Can someone provide an example of creating the stylesheet
programatically to pass to an XslTransform.Load method?
Do I just write out the XML to a string?

Maybe my example from before would help...

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:template match="NewDataSet" >
<MyDataSet>
<xsl:apply-templates select="Cust" />
</MyDataSet>
</xsl:template>
<xsl:template match="Cust">
<MyCustomer>
<xsl:apply-templates select="nameFirst" />
<xsl:apply-templates select="nameLast" />
<xsl:apply-templates select="addrCity" />
<xsl:apply-templates select="addrState" />
<xsl:apply-templates select="addrStreet" />
<xsl:apply-templates select="addrZIP" />
</MyCustomer>
</xsl:template>

<xsl:template match="nameFirst">
<MyFname>
<xsl:value-of select="text()" />
</MyFname>
</xsl:template>
<xsl:template match="nameLast">
<MyLname>
<xsl:value-of select="text()" />
</MyLname>
</xsl:template>
<xsl:template match="addrCity">
<MyCity>
<xsl:value-of select="text()" />
</MyCity>
</xsl:template>
<xsl:template match="addrState">
<MyState>
<xsl:value-of select="text()" />
</MyState>
</xsl:template>
<xsl:template match="addrStreet">
<MyStreet>
<xsl:value-of select="text()" />
</MyStreet>
</xsl:template>
<xsl:template match="addrZIP">
<MyZIPPO>
<xsl:value-of select="text()" />
</MyZIPPO>
</xsl:template>
</xsl:stylesheet>
Thanks in advance,
Pint
Nov 12 '05 #1
7 5169
pintihar wrote:
As a follow on from an earlier post I have another question about
xslt.
Is it possible to create the stylsheet programatically? Is this
sensible? In the first phase I needed to map element name from inbound
xml to my internal elements to standardize disparate input.
Now I could just create an xslt stylesheet for each possible inbound
format and be done, but I think it would be powerful to be able store
this mapping in a database and programatically create the stylsheet.


Instead of creating stylesheet each time programatically (I'm not aware
of any of such facilities) you can go this way: define format of mapping
XML document, which defines required mapping and write (once) generic
stylesheet, which transforms documents basing on the mapping.
Alternatively you can have generic stylesheet, which generates specific
stylesheets according to provided mapping (that's very easy to generate
XSLT with XSLT).

--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #2
>> As a follow on from an earlier post I have another question about
xslt.
Is it possible to create the stylsheet programatically? Is this
sensible? In the first phase I needed to map element name from inbound
xml to my internal elements to standardize disparate input.
Now I could just create an xslt stylesheet for each possible inbound
format and be done, but I think it would be powerful to be able store
this mapping in a database and programatically create the stylsheet.


Instead of creating stylesheet each time programatically (I'm not aware
of any of such facilities) you can go this way: define format of mapping
XML document, which defines required mapping and write (once) generic
stylesheet, which transforms documents basing on the mapping.
Alternatively you can have generic stylesheet, which generates specific
stylesheets according to provided mapping (that's very easy to generate
XSLT with XSLT).


Are you suggesting in the first case, that the mapping would imposed
on the writer of the inbound xml to conform to a known format? This is
not possible as I have no control over the format of the inbound xml,
Just that the element names will be predictable: City State, Zip...
But differ slightly based on the actual source of the file: fname
versus FirstName.

I like the sound of the later, but on my reading, it seems to restate
my question: How do I generate xslt?

Thanks again,
Phil
Nov 12 '05 #3
pintihar wrote:
Are you suggesting in the first case, that the mapping would imposed
on the writer of the inbound xml to conform to a known format?
Nope, leave alone inbound XML, but define your own mapping XML, which
defines how to map inbound elements to outbound ones. Something like

<mapping>
<rule inbound="foo" outbound="bar"/>
</mapping>

Then in XSLT you can look up for mapping and output elements according
to rules:

<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
<xsl:otherwise>
<!-- No mapping - copy as is -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:otherwise>
</xsl:choose>
</xsl:template>

I like the sound of the later, but on my reading, it seems to restate
my question: How do I generate xslt?


XSLT is XML, so the question is how to create XML with XSLT. The only
thing to note is xsl:namespace-alias instruction, which allows to alias
elements of generated XML to distinguish them from XSLT instructions:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

<xsl:template match="/">
<axsl:stylesheet>
<xsl:apply-templates/>
</axsl:stylesheet>
</xsl:template>

<xsl:template match="block">
<axsl:template match="{.}">
<fo:block><axsl:apply-templates/></fo:block>
</axsl:template>
</xsl:template>

</xsl:stylesheet>

--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Nov 12 '05 #4
On Thu, 04 Mar 2004 19:07:26 +0200, "Oleg Tkachenko [MVP]"
<oleg@NO!SPAM!PLEASEtkachenko.com> wrote:
pintihar wrote:
Are you suggesting in the first case, that the mapping would imposed
on the writer of the inbound xml to conform to a known format?


Nope, leave alone inbound XML, but define your own mapping XML, which
defines how to map inbound elements to outbound ones. Something like

<mapping>
<rule inbound="foo" outbound="bar"/>
</mapping>

Then in XSLT you can look up for mapping and output elements according
to rules:

<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
<xsl:otherwise>
<!-- No mapping - copy as is -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:otherwise>
</xsl:choose>
</xsl:template>


Thanks for the help so far.
I am unable to get your example to work.

No matter whay I try, I cannot get the test to return true. I cannont
find examples of the document function either.

Could you please show me a hello world example of how one would grab
values from another xml file using the document function?

Thanks,
Pint
Nov 12 '05 #5
>On Thu, 04 Mar 2004 19:07:26 +0200, "Oleg Tkachenko [MVP]"
<oleg@NO!SPAM!PLEASEtkachenko.com> wrote:
pintihar wrote:
Are you suggesting in the first case, that the mapping would imposed
on the writer of the inbound xml to conform to a known format?


Nope, leave alone inbound XML, but define your own mapping XML, which
defines how to map inbound elements to outbound ones. Something like

<mapping>
<rule inbound="foo" outbound="bar"/>
</mapping>

Then in XSLT you can look up for mapping and output elements according
to rules:

<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
<xsl:otherwise>
<!-- No mapping - copy as is -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:otherwise>
</xsl:choose>
</xsl:template>


Thanks for the help so far.
I am unable to get your example to work.

No matter whay I try, I cannot get the test to return true. I cannont
find examples of the document function either.

Could you please show me a hello world example of how one would grab
values from another xml file using the document function?

Thanks,
Pint


Save ME!!!!

Well I finally determinded that my xsl works correctly when loaded in
a browser from within the xml file:
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>

But, when called from within dotnet the I believe that the document
function is not working. I read about the need to use the
XmlUrlResolver object, but I can not seem to get this working.

It is hard enough to grok xsl syntax, can you explain why these files
work differenly when used in dotnet?

Thanks,
Phil

# test.xsl
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

----

#newtest.xml
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>
<NewDataSet>
<Lead>
<nameFirst>JACK</nameFirst>
<nameLast>Smith</nameLast>
<addrCity>Cleveland</addrCity>
<addrState>OH</addrState>
<addrStreet>200 Main</addrStreet>
<addrZIP>46140</addrZIP>
</Lead>
</NewDataSet>

----

#mapping.xml
<mapping>
<rule inbound="nameFirst" outbound="My_First_Name"/>
</mapping>

----
# dotnet code
#Attempt to call from dotnet ( xsl removed from stylsheet)

XslTransform tr = new XslTransform();
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

tr.Load("test.xsl",resolver);
tr.Transform("newtest.xml", "TransformResult.xml", null);

----

Nov 12 '05 #6
On Fri, 05 Mar 2004 02:54:18 GMT, pintihar <pi******@earthlink.net>
wrote:
On Thu, 04 Mar 2004 19:07:26 +0200, "Oleg Tkachenko [MVP]"
<oleg@NO!SPAM!PLEASEtkachenko.com> wrote:
pintihar wrote:

Are you suggesting in the first case, that the mapping would imposed
on the writer of the inbound xml to conform to a known format?

Nope, leave alone inbound XML, but define your own mapping XML, which
defines how to map inbound elements to outbound ones. Something like

<mapping>
<rule inbound="foo" outbound="bar"/>
</mapping>

Then in XSLT you can look up for mapping and output elements according
to rules:

<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
<xsl:otherwise>
<!-- No mapping - copy as is -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:otherwise>
</xsl:choose>
</xsl:template>


Thanks for the help so far.
I am unable to get your example to work.

No matter whay I try, I cannot get the test to return true. I cannont
find examples of the document function either.

Could you please show me a hello world example of how one would grab
values from another xml file using the document function?

Thanks,
Pint


Save ME!!!!

Well I finally determinded that my xsl works correctly when loaded in
a browser from within the xml file:
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>

But, when called from within dotnet the I believe that the document
function is not working. I read about the need to use the
XmlUrlResolver object, but I can not seem to get this working.

It is hard enough to grok xsl syntax, can you explain why these files
work differenly when used in dotnet?

Thanks,
Phil

# test.xsl
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="*">
<xsl:variable name="rule"
select="document('mapping.xml')/mapping/rule[@inbound=name(current())]"/>
<xsl:choose>
<xsl:when test="$rule">
<xsl:element name="{$rule/@outbound}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

----

#newtest.xml
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>
<NewDataSet>
<Lead>
<nameFirst>JACK</nameFirst>
<nameLast>Smith</nameLast>
<addrCity>Cleveland</addrCity>
<addrState>OH</addrState>
<addrStreet>200 Main</addrStreet>
<addrZIP>46140</addrZIP>
</Lead>
</NewDataSet>

----

#mapping.xml
<mapping>
<rule inbound="nameFirst" outbound="My_First_Name"/>
</mapping>

----
# dotnet code
#Attempt to call from dotnet ( xsl removed from stylsheet)

XslTransform tr = new XslTransform();
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = CredentialCache.DefaultCredentials;

tr.Load("test.xsl",resolver);
tr.Transform("newtest.xml", "TransformResult.xml", null);

----


Woo Hoo. I got it.
The XmlUrlResolver is needed to use the 'document' function in xsl.
In my earlier posts, although I used it in the XslTransform.Load
methoh, I did not supply it to the Transform method.

Well it serves me right for trying to run before I knew how to walk.

Thanks for the assistance Oleg and Derek
-Pint
Nov 12 '05 #7
pintihar,
Is it possible to create the stylsheet programatically? Remember that a stylesheet is simply an XML document, so you could use any
of the objects in .NET that create XML documents to create a stylesheet. I
would probably use an XmlTextWriter. Something like:

Const ns As String = "http://www.w3.org/1999/XSL/Transform"
Const prefix As String = "xsl"

Dim writer As New Xml.XmlTextWriter("stylesheet.xslt",
System.Text.Encoding.Default)
' <?xml version="1.0" ?>
writer.WriteStartDocument()

' <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
writer.WriteStartElement(prefix, "stylesheet", ns)
' version="1.0">
writer.WriteAttributeString("version", "1.0")
' <xsl:template match="NewDataSet" >
writer.WriteStartElement(prefix, "template", ns)
writer.WriteAttributeString("match", "NewDataSet")

' <MyDataSet>
writer.WriteStartElement("MyDataSet")

' <xsl:apply-templates select="Cust" />
writer.WriteStartElement(prefix, "apply-templates", ns)
writer.WriteAttributeString("select", "Cust")
writer.WriteEndElement()

' </MyDataSet>
writer.WriteEndElement()

....

' </xsl:stylesheet>
writer.WriteEndElement()
writer.WriteEndDocument()
writer.Close()

Is this
sensible? Maybe. See Oleg's comments.

Hope this helps
Jay

"pintihar" <pi******@earthlink.net> wrote in message
news:ld********************************@4ax.com... Hi,
As a follow on from an earlier post I have another question about
xslt.
Is it possible to create the stylsheet programatically? Is this
sensible? In the first phase I needed to map element name from inbound
xml to my internal elements to standardize disparate input.
Now I could just create an xslt stylesheet for each possible inbound
format and be done, but I think it would be powerful to be able store
this mapping in a database and programatically create the stylsheet.
This way I don't have to maintain potentially a great number of
stylesheets. The trouble is, I can't find any example where the
stylesheet is not Load'ed from a file.

Can someone provide an example of creating the stylesheet
programatically to pass to an XslTransform.Load method?
Do I just write out the XML to a string?

Maybe my example from before would help...

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:template match="NewDataSet" >
<MyDataSet>
<xsl:apply-templates select="Cust" />
</MyDataSet>
</xsl:template>
<xsl:template match="Cust">
<MyCustomer>
<xsl:apply-templates select="nameFirst" />
<xsl:apply-templates select="nameLast" />
<xsl:apply-templates select="addrCity" />
<xsl:apply-templates select="addrState" />
<xsl:apply-templates select="addrStreet" />
<xsl:apply-templates select="addrZIP" />
</MyCustomer>
</xsl:template>

<xsl:template match="nameFirst">
<MyFname>
<xsl:value-of select="text()" />
</MyFname>
</xsl:template>
<xsl:template match="nameLast">
<MyLname>
<xsl:value-of select="text()" />
</MyLname>
</xsl:template>
<xsl:template match="addrCity">
<MyCity>
<xsl:value-of select="text()" />
</MyCity>
</xsl:template>
<xsl:template match="addrState">
<MyState>
<xsl:value-of select="text()" />
</MyState>
</xsl:template>
<xsl:template match="addrStreet">
<MyStreet>
<xsl:value-of select="text()" />
</MyStreet>
</xsl:template>
<xsl:template match="addrZIP">
<MyZIPPO>
<xsl:value-of select="text()" />
</MyZIPPO>
</xsl:template>
</xsl:stylesheet>
Thanks in advance,
Pint

Nov 12 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Doug Farrell | last post by:
Hi all, I'm trying to use the 4Suite xml/xsl tools to transform some XML data into HTML. I'm using some examples from the O'Reilly book "Python and XML" and things are blowing up. Here is the...
6
by: Pete | last post by:
I am just getting to grips with XML and I was wondering if you could help me with something that no-one seems able or willing to help with.. I have an XSLT file which should be transforming a...
1
by: Mohit | last post by:
Hi Friends I have to call 1 of the 2 child XSLT files from the Main XSLT file based on some criteria. I want one child XSLT file will be executed by version 1 of XSLT processor and the other by...
12
by: gipsy boy | last post by:
Hello, I have sort of a big problem. I would really appreciate any help you could give me. I made a web service in C++ that throws XML to the client (browser). But, the XSLT transormation...
14
by: David Blickstein | last post by:
I have some XML documents that I want to open in a web browser and be automatically translated to HTML via XSLT. I'm using an xml-stylesheet processing command in a file called "girml.xml". ...
3
by: IMS.Rushikesh | last post by:
Hi Friends, I need a XPath query, whcih ll return me subset of data.... check below xml stream <label id="MyExpenseDetails_lbl" xlink:role="terseLabel">Short Expense Details</label> <label...
3
by: Alex | last post by:
I stumbled upon this while developing a custom XPathNavigator. It appears that copy action for attributes is broken in the .net framework XSLT processor. The intent was to just copy the entities...
6
by: Neal | last post by:
Hi All, I wrote a TOC treeview using xml and xslt, with help from this forum and MSDN help(thanks) Great in IE 6. (expect IE 5 as well, articles were circa 2000) However, Mozilla FireFox...
18
by: yinglcs | last post by:
Hi, I have a newbie XSLT question. I have the following xml, and I would like to find out the children of feature element in each 'features' element. i.e. for each <featuresI would like to...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.