I am trying to write XSLT to transform my XML from one format to another. When I apply my .xslt file to the XML file in VS 2010, the output XML structure is created without any problem. But it does not fill in data expected by processing xsl:value-of.
When I use XMLSpy and evaluate the XPath expression, it says no result for the expressions in following XSLT. But when I use node() function at the end of the XPath expression, it shows the value!
- What is the correct way of writing XPath?
- Does
node()andtext()kind of functions really necessary everytime to read the element content (when it has no child elements) ? If no, why XmlSpy too does not give result without those functions? - Sometimes (when i change the template match value from “/” to the “ServiceMessage” ) while debugging XSLT, VS 2010 steps into built in template rules. Why is it so? How can I get rid of built in templates in VS 2010?
I have followed w3school tutorial to begin with. I am new to XSLT.
Here is my XML which I want to transform to some other XML format.
<ServiceMessage xmlns="http://requestservice/requests" xmlns:req="http://requestservice/requests/xmlstds">
<TypeOfReq> General </TypeOfReq>
<Details>
<Id> 123456789 </Id>
<SenderDetails>
<Sender id="345"></Sender>
</SenderDetails>
</Details>
</ServiceMessage>
This is my XSLT
<?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" indent="yes"/>
<xsl:template match="/">
<request>
<requestType>
<xsl:value-of select="ServiceMessage/TypeOfReq" />
</requestType>
<Id>
<xsl:value-of select="ServiceMessage/Details/Id"/>
</Id>
<senderId>
<xsl:value-of select="ServiceMessage/Details/SenderDetails/Sender/@id"/>
</senderId>
</request>
</xsl:template>
</xsl:stylesheet>
You have written the xpath correctly from a syntatic point of view. The problem you are actually having is actually to do with namespaces. In your XML you have specified a default namespace
This means all the child elements, unless otherwise specified, with belong to that namespace. However, in your XSLT, there is no reference to this namepsace at all, and so the XSLT is looking for elements which do not have a namespace specified. This is not the case for your XML.
For XSLT 1.0, you will need to declare the namespace, like so:
You would then explicitly state where it is used for matching the elements
Here is the full XSLT
When applied to your XML, the following is output
Do note the choice of the letter ‘s’ here is purely arbitrary, it could be anything really.