cookiejar
asked on
XML Namespace with XPATH
After adding namespaces to my xml document, my xsl doc no longer return results. Could you please tell me what I am doing wrong? I am a student and is not familiar with this technology.
I have set up a default and prefixed namespace. I don't know how to reference these in the xsl file. I am not sure if I have set the namespaces up correctly .
See my attachments.
contacts-2.xml
contacts.xsl
I have set up a default and prefixed namespace. I don't know how to reference these in the xsl file. I am not sure if I have set the namespaces up correctly .
See my attachments.
contacts-2.xml
contacts.xsl
<xsl:stylesheet version="1.0"
xmlns:fam="http://www.nathan.com/ns/family"
xmlns:fr="http://www.nathan.com/ns/friend"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<!--
Name: Marilyn Nathan
Date: 24 Feb 2015
Course#: CIS 205
Assignment#: Module 2 Project 2
-->
<html>
<head>
<title>My Contacts</title>
</head>
<body>
<h1>My Contacts</h1>
<h2>Family</h2>
<table border="1" style="width:90%">
<tbody>
<tr bgcolor="#FAFAFA">
<th style="text-align:center">Name</th>
<th style="text-align:center">Address</th>
<th style="text-align:center">City</th>
<th style="text-align:center">State</th>
<th style="text-align:center">Zip Code</th>
<th style="text-align:center">Phone</th>
<th style="text-align:center">Birthday</th>
<th style="text-align:center">Favorite Color</th>
</tr>
<xsl:for-each select="//fam:family">
<xsl:sort select="fam:name"/>
<tr>
<td><xsl:apply-templates select="fam:name"/></td>
<td><xsl:apply-templates select="fam:address"/></td>
<td><xsl:apply-templates select="fam:city"/></td>
<td><xsl:apply-templates select="fam:state"/></td>
<td align="right"><xsl:apply-templates select="fam:zip_code"/></td>
<td align="right"><xsl:apply-templates select="fam:phone"/></td>
<td align="right"><xsl:apply-templates select="fam:birthday"/></td>
<td><xsl:apply-templates select="@favcolor"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
<h2>Friends</h2>
<table border="1" style="width:90%" >
<tbody>
<tr bgcolor="#FAFAFA">
<th style="text-align:center">Name</th>
<th style="text-align:center">Address</th>
<th style="text-align:center">City</th>
<th style="text-align:center">State</th>
<th style="text-align:center">Zip Code</th>
<th style="text-align:center">Phone</th>
<th style="text-align:center">Birthday</th>
<th style="text-align:center">Favorite Color</th>
</tr>
<xsl:for-each select="//fr:friend">
<xsl:sort select="name"/>
<tr>
<td><xsl:apply-templates select="fr:name"/></td>
<td><xsl:apply-templates select="fr:address"/></td>
<td><xsl:apply-templates select="fr:city"/></td>
<td><xsl:apply-templates select="fr:state"/></td>
<td align="right"><xsl:apply-templates select="fr:zip_code"/></td>
<td align="right"><xsl:apply-templates select="fr:phone"/></td>
<td align="right"><xsl:apply-templates select="fr:birthday"/></td>
<td><xsl:apply-templates select="@favcolor"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
above XSLT has fixed the issue
Let me make one comment.
It is good that you experiment with namespaces.
But namespaces are used to avoid name clashes for things that have the same name but a different meaning
or to group things that belong together
In your XML you have made fam:name and fr:name two different things
That actually is a poor use of namespaces, because regardless the fact that they are naming either a friend or a family.... it is the name of a person. In my XML I would definitely make sure that fam:name and fr:name were the same thing
I know you are just experimenting likely, and you are learning
but please take that lesson for granted
Let me make one comment.
It is good that you experiment with namespaces.
But namespaces are used to avoid name clashes for things that have the same name but a different meaning
or to group things that belong together
In your XML you have made fam:name and fr:name two different things
That actually is a poor use of namespaces, because regardless the fact that they are naming either a friend or a family.... it is the name of a person. In my XML I would definitely make sure that fam:name and fr:name were the same thing
I know you are just experimenting likely, and you are learning
but please take that lesson for granted
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
If I change to the following:
<contacts
xmlns:fam="http://www.nathan.com/ns/family"
xmlns:fr="http://www.nathan.com/ns/friend"
xmlns:per="http://www.nathan.com/ns/person"
>
Do I still use fam: and fr: as the prefixes at the parent level in the XSL doc? <xsl:for-each select="//fam:family"> and <xsl:for-each select="//fr:family">
Do I prefix the children with per? <td><xsl:apply-templates select="per:name"/></td>
<td><xsl:apply-templates select="per:address"/></td >
Also, in what cases would one use namespace?
Thanks you for your excellent help.
<contacts
xmlns:fam="http://www.nathan.com/ns/family"
xmlns:fr="http://www.nathan.com/ns/friend"
xmlns:per="http://www.nathan.com/ns/person"
>
Do I still use fam: and fr: as the prefixes at the parent level in the XSL doc? <xsl:for-each select="//fam:family"> and <xsl:for-each select="//fr:family">
Do I prefix the children with per? <td><xsl:apply-templates select="per:name"/></td>
<td><xsl:apply-templates select="per:address"/></td
Also, in what cases would one use namespace?
Thanks you for your excellent help.
Yes, that is how to do that
you need to know that you define an element in a namespace
by saying "this element is part of that namespace"
You can do so by having a default namespace or by adding a prefix (and a prefix binding)
What the prefix is does not matter, the namespace uri it is bound to is important
<fam:family xmlns:fam="http://www.nathan.com/ns/family"/>
and
<foo:family xmlns:foo="http://www.nathan.com/ns/family"/>
though the prefix is different, the elements are associated to the same namespace
you use namespaces as I said earlier to:
you need to know that you define an element in a namespace
by saying "this element is part of that namespace"
You can do so by having a default namespace or by adding a prefix (and a prefix binding)
What the prefix is does not matter, the namespace uri it is bound to is important
<fam:family xmlns:fam="http://www.nathan.com/ns/family"/>
and
<foo:family xmlns:foo="http://www.nathan.com/ns/family"/>
though the prefix is different, the elements are associated to the same namespace
you use namespaces as I said earlier to:
namespaces are used to avoid name clashes for things that have the same name but a different meaning
or to group things that belong together
This is an issue that hits every XSLT developer at least once :-)
In your XML you are using a default namespace
xmlns="http://www.nathan.com/ns/family"
xmlns:fr="http://www.nathan.com/ns/friend"
But usually in your XSLT the default namespace is used for the output tree
so the default namespace is taken
so you need to add a prefix for the default namespace from the source doc as well
xmlns:fam="http://www.nathan.com/ns/family"
xmlns:fr="http://www.nathan.com/ns/friend"
in your stylesheet element
and then use the prefixes in the XPaths