Problem while transforming an XML into another XML file

Here should go questions about transforming XML with XSLT and FOP.
jekkil
Posts: 3
Joined: Tue Apr 25, 2006 10:48 am
Location: Belgium

Problem while transforming an XML into another XML file

Post by jekkil »

Hi everyone !

I post here because I am facing some filtering problem: I want to transform an XML to another one. The output should only take some of the data of the input one and the other element of the input should be ignored.

Here is the input xml file I use:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Network_Fulfilment_Request xmlns="http://mobile.belgacom.be/fiona/xml/cl">
<Body>
<Registered_End_User>
<REU_ID>
<ID>1245</ID>
</REU_ID>
<Details>
<Gender>false</Gender>
</Details>
</Registered_End_User>
<Subscription>
<Product_Subscriptions>
<Installed_CFSs>
<CFS>
<CFS_Identifier>12</CFS_Identifier>
<Description>description</Description>
<Action>U</Action>
</CFS>
<CFS_Parameter>
<Parameter_Type_ID>NetworkID</Parameter_Type_ID>
<Parameter_Value>netw0</Parameter_Value>
</CFS_Parameter>
<CFS_Parameter>
<Parameter_Type_ID>TransactionID</Parameter_Type_ID>
<Parameter_Value>123456789</Parameter_Value>
</CFS_Parameter>
<CFS_Parameter>
<Parameter_Type_ID>IsMobile</Parameter_Type_ID>
<Parameter_Value>0</Parameter_Value>
</CFS_Parameter>
</Installed_CFSs>
</Product_Subscriptions>
</Subscription>
</Body>
</Network_Fulfilment_Request>
The XSL file I have defined:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns="http://mobile.belgacom.be/fiona/xml"
xmlns:cl="http://mobile.belgacom.be/fiona/xml/cl">

<xsl:template match="/">
<request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mobile.belgacom.be/fiona/xml file:/C:/Workspace/Fiona/trunk/xsd/request.xsd">
<xsl:apply-templates/>
</request>
</xsl:template>

<xsl:template match="cl:Action" priority="0.5">
<param>
<key>REQ_TYPE</key>
<value>
<xsl:value-of select="."/>
</value>
</param>
</xsl:template>

<xsl:template match="cl:CFS_Parameter" priority="0.5">
<param>
<key>
<xsl:value-of select="cl:Parameter_Type_ID"/>
</key>
<value>
<xsl:value-of select="cl:Parameter_Value"/>
</value>
</param>
</xsl:template>

<xsl:template match="*" priority="0.1"/>

</xsl:stylesheet>
The output of the transformation is:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<request xmlns="http://mobile.belgacom.be/fiona/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cl="http://mobile.belgacom.be/fiona/xml/cl"
xsi:schemaLocation="http://mobile.belgacom.be/fiona/xml file:/C:/Workspace/Fiona/trunk/xsd/request.xsd"/>
This means that the template

Code: Select all

<xsl:template match="*" priority="0.1"/>
matches everything.
Is there a way to prevent that the last template does not overide the the other when they are applicable ?

I have tried to tune with priority but without any success :-(

The expected output should be

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<request xmlns="http://mobile.belgacom.be/fiona/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cl="http://mobile.belgacom.be/fiona/xml/cl"
xsi:schemaLocation="http://mobile.belgacom.be/fiona/xml file:/C:/Workspace/Fiona/trunk/xsd/request.xsd">
<param><key>REQ_TYPE</key><value>U</value></param>
<param><key>NetworkID</key><value>netw0</value></param>
<param><key>TransactionID</key><value>123456789</value></param>
<param><key>IsMobile</key><value>0</value></param>
</request>
jekkil
Posts: 3
Joined: Tue Apr 25, 2006 10:48 am
Location: Belgium

Post by jekkil »

I think I have found the problem:
The rule

Code: Select all

<xsl:template match="*" priority="0.1"/>
matches any element, even the root one so the first element (the root one) is skipped by this rule and the process finishes there.
Using a rule like

Code: Select all

<xsl:template match="text()" priority="0.1"/>
seems to resolve this.
If someone has a better idea, it's welcomed.
Jekkil
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi Jekkil,

Have a look at the default templates:
http://www.w3.org/TR/xslt#built-in-rule

As you can see by default an XSLT processor when matching an element or the document node will apply the templates on its content (but not on its attributes) and when matching text or attribute nodes will output their values.
When the processing starts the context node is the document node.

Initially you added a template to match all the elements and as you noted the root element was matched by that and no output was produced further.
After that you matched the text modes and you did nothing there, thus no unwanted text node will appear in the generated output that would have been caused otherwise by the default template that matches the text nodes.

Eventually to understand better the processing you can add default templates in a stylesheet and import that stylesheet in yout main stylesheet then use the oXygen debugger to step through the transformation and see what templates are invoked.

Best Regards,
George
jekkil
Posts: 3
Joined: Tue Apr 25, 2006 10:48 am
Location: Belgium

Post by jekkil »

Thanks George.

Importing the default builtin templates is a very good suggestion. It helps a lot to understand how this works with the XSLT debugger.

Thanks again ! :D
Jekkil
Post Reply