473,405 Members | 2,444 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,405 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 5175
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.