This site has been taken over by the staff of www.ASPDeveloper.Net

Please report errors to suggest@aspdeveloper.net

BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
XSLT
Database Web Application Wizard
XLink: Creating Powerful, Flexible Hypertext Structures
What are XPath Match Patterns?
Formally Defining XPath Match Patterns
XPath Pattern Examples
Creating XPath Predicates
Using XPath Predicates
VoiceXML with XSLT
XSLT Quickly
The Functional Programming Language XSLT - A proof through examples
The Understanding XSL Game
Dynamic functions: Functional combination, partial application and lambda expressions
XSLT Stylesheets, find over 100 example XSLT stylesheets
XSLT - Creating Links and Cross-References
XML in a Nutshell - XPath
The XPath Function: node-set unparsed-entity-url ( string )
The XPath Function: boolean true ( )
The XPath Function: string translate ( string, string, string )
The XPath Function: object system-property ( string )
The XPath Function: number sum ( node-set )
<< XQuery
.NET and XML >>

By :Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First posted :05/18/2004
Times viewed :16790

 

None of my XPath select statements will work going against an XML file with a default namespace. Help!

by Mark Bosley

Back in college, on the night before a final exam, every subject humanity has ever considered became utterly fascinating to me. Every subject that is, except the subject about which I was to be tested on the next morning. My wife says she would end up cleaning the night before an exam. And me? I would end up in the library reading the Encyclopaedia Britannica, leafing through it page by page. I felt good about ignoring my exam the next day if I ended up studying a subject that I was to study the next semester.

Well, things haven't changed that much. I was recently stuck with an XPath problem and so what did I do? Well, I read the XSLT 2 requirements document. Never mind that it will be at least a year until we see any implementation of XSLT 2.0, it just that it was so fascinating. My procrastination this time, however, actually paid off.

The Problem

I was working with the following XML DOM being returned via ServerXMLHTTP. It has two namespaces: one associated with the prefix cs and one with no prefix, which is called a 'default' namespace. 

The XML Dom being returned was from outside my company, I had to deal with it. I had so much trouble that I investigated programmatically removing a namespace.

This proved to be very hard-because it is impossible. Another person on the project put the DOM into a string, removed the namespace and then reloaded the DOM. This seemed too kludgey and slow for me.

What follows is the xml dom and the stylesheet I was trying to use. This resulted in <root></root> but not in <root><gotHere>.....

<requestHierarchySelectResult resultName="" 
	xmlns="http://www.lightcc.com/ns"
	xmlns:cs="http://www.customsolids.com">
    <request>
        <created_dt>05/05/2000 00:00:00</created_dt>
        <created_tm>01/01/1900 14:02:46</created_tm>
        <cs:request_id>100002</cs:request_id>
    </request>
</requestHierarchySelectResult>

 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
	<root><xsl:apply-templates  select="/*/request"/></root>
</xsl:template>

<xsl:template  match="*|@*|node()"/>

<xsl:template  match="request">
   <gotHere><xsl:value-of  select="."/></gotHere>
</xsl:template>

</xsl:stylesheet>

I thought I came to a solution when I realized I needed the namespaces in the XML file also declared in the stylesheet. So, I added the namespaces to the style sheet from the xml file. But, it still did not produce <root><gotHere>......

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"	
xmlns
="http://www.lightcc.com/ns" xmlns:cs="http://www.customsolids.com"
> <xsl:template match="/"> <root><xsl:apply-templates select="/*/request"/></root> </xsl:template> <xsl:template match="*|@*|node()"/> <xsl:template match="request"> <gotHere><xsl:value-of select="."/></gotHere> </xsl:template> </xsl:stylesheet>

I could get something with unwieldy XPath queries like <xsl:apply-templates select="*/*[local-name()='request']"/>

But, to do a whole stylesheet like that would be a chore.

An answer from Dimitre Novatchev, helped the lights go on.

The problem is that I did not understand that namespaces link an XML and XSLT file thru the URI, not the prefix. So the (simple) solution is to add a prefix in the xslt file and then use the prefix in the XPath statements (lc in the stylesheet below) 


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"	
xmlns:lc
="http://www.lightcc.com/ns" xmlns:cs="http://www.customsolids.com"
> <xsl:template match="/"> <root><xsl:apply-templates select="/*/lc:request"/></root> </xsl:template> <xsl:template match="*|@*|node()"/> <xsl:template match="lc:request"> <gotHere><xsl:value-of select="."/></gotHere> </xsl:template> </xsl:stylesheet>

Although the answer from Dimitre helped, it wasn't until I read the requirements document for the next version of XSLT. Here is the relevant portion.

         2.1 Must Allow Matching on Default Namespace Without Explicit Prefix

Many users stumble trying to match an element with a default namespace. They expect to be able to do something like:

<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns="urn:myuri">
  <!-- Expect this matches <foo> in default namespace -->
  <xsl:template match="foo">

thinking that leaving off the prefix from the foo element name, that it will match <foo> elements in the default namespace with the URI of urn:myuri. Instead, they are required to assign a non-null prefix name to their namespace URI and then match on "someprefix:foo" instead, which has proven to be far from obvious . XSLT 2.0 SHOULD provide an explicit way to handle this scenario to avoid further user confusion.

So, in conclusion, reading the requirements documents will help you understand the roadblocks that a wide range of programmer's are running into.

Below are links for the requirements documents for XSLT 2.0 and XPath 2.0

http://www.w3.org/TR/xslt20req

http://www.w3.org/TR/xpath20req

Mark Bosley is a programmer who lives in Shorewood, Wisconsin. His laziness leads him to investigate all sorts of declarative programming tools because he's confident the computer is smarter at figuring out how to do things than he is. He works for Northwoods Software Development, Inc. You can reach him at mark@lightcc.com


Rate this article on a scale of 1 to 10

Your vote :  


 

Recent Jobs

Software Specialist, Linux - Finlan
Linux Core Technical Project Manage
Graphics designer at Tanzania. Expe
Integration Specialist Needed - Wor
Virtualization Server Infrastructur

View all Jobs (Add yours)
View all CV (Add yours)






    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP