namespace error : Namespace prefix bd on keyword is not defined
Suppose you have following XML:
<root>
<book>
<name>A</name>
<description>A1</description>
</book>
<book>
<name>B</name>
<description>B1</description>
</book>
</root>
Desired XML (with namespaces):
<root xmlns:bd="namespace1" xmlns:pd="namespace2">
<bd:Book>
<bd:Name>A</bd:Name>
<pd:Description>A1</pd:Description>
</bd:Book>
<bd:Book>
<bd:Name>B</bd:Name>
<pd:Description>B1</pd:Description>
</bd:Book>
</root>
Appropriate XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bd="namespace1"
xmlns:pd="namespace2"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="book">
<bd:Book>
<xsl:apply-templates />
</bd:Book>
</xsl:template>
<xsl:template match="name">
<bd:Name>
<xsl:value-of select="."/>
</bd:Name>
</xsl:template>
<xsl:template match="description">
<pd:Description>
<xsl:value-of select="."/>
</pd:Description>
</xsl:template>
</xsl:stylesheet>
You simply add namespaces in XSLT, then create nodes using namespace's prefix.
Update 1:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pd="namespace2"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="book">
<bd:Book xmlns:bd="namespace1">
<xsl:apply-templates />
</bd:Book>
</xsl:template>
<xsl:template match="name">
<bd:Name xmlns:bd="namespace1">
<xsl:value-of select="."/>
</bd:Name>
</xsl:template>
<xsl:template match="description">
<pd:Description>
<xsl:value-of select="."/>
</pd:Description>
</xsl:template>
</xsl:stylesheet>
Update 2:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pd="namespace2"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="book">
<Book xmlns="namespace1">
<xsl:apply-templates />
</Book>
</xsl:template>
<xsl:template match="name">
<Name xmlns="namespace1">
<xsl:value-of select="."/>
</Name>
</xsl:template>
<xsl:template match="description">
<pd:Description>
<xsl:value-of select="."/>
</pd:Description>
</xsl:template>
</xsl:stylesheet>
Update 3: This XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="book">
<pd:Book xmlns:pd="namespace2">
<xsl:apply-templates />
</pd:Book>
</xsl:template>
<xsl:template match="name">
<pd:Name xmlns:pd="namespace2">
<xsl:value-of select="."/>
</pd:Name>
</xsl:template>
<xsl:template match="description">
<pd:Description xmlns:pd="namespace2">
<xsl:value-of select="."/>
</pd:Description>
</xsl:template>
</xsl:stylesheet>
Output XML (like in your Update 2, I use MSXML 6.0), but for XML engine no matter where namespace is defined:
<root>
<pd:Book xmlns:pd="namespace2">
<pd:Name>A</pd:Name>
<pd:Description>A1</pd:Description>
</pd:Book>
<pd:Book xmlns:pd="namespace2">
<pd:Name>B</pd:Name>
<pd:Description>B1</pd:Description>
</pd:Book>
</root>
Related videos on Youtube
lightonphiri
I use Ubuntu; primarily use Bash& Python for my immediate scripting needs, and have a passion for data& storage infrastructure.
Updated on June 04, 2022Comments
-
lightonphiri almost 2 years
I have a huge xml file that I would like to split up into individual xml documents; each individual xml file is supposed to have an explicit namespace declaration where applicable as show in the "Desired Output" portion below. However, I keep getting the error "namespace error : Namespace prefix bd on keyword is not defined"
My question is, how can I explicitly tell my XSLT processor where to put namespace declaration in resulting output? I have gone through a couple of tutorials online, but I can't quite figure out how to sort this out.
Partial XSLT Snippet
... ... <xsl:template match="chapter"> <bd:chapter> <xsl:apply-templates select="name" /> <xsl:apply-templates select="page" /> </bd:chapter> </xsl:template> <xsl:template match="name"> <bd:name> <xsl:value-of select="." /> </bd:name> </xsl:template> ... ...
Desired Output
<?xml version="1.0" encoding="utf-8" ?> <books> <bd:book xmlns:bd="http://www.bd.org.za/db" xmlns:cd="http://www.bd.org.za/cd"> <bd:name>book01</bd:name> <bd:chapter> <cd:name>chapter01<cd:name> <bd:page> <cd:title></cd:title> <pd:description></pd:description> </bd:page> </bd:chapter> </bd:book> ... ... ... </books>
Update #1
<?xml version="1.0" encoding="utf-8" ?> <books> <book> <name>book01</name> <chapter> <name>chapter01<name> <page> <title></title> <description></description> </page> </chapter> </book> ... ... ... </books>
Update #2
@polishchuk Update2 give the following result
<?xml version="1.0"?> <root xmlns:pd="namespace2"> <pd:Book xmlns:pd="http://namespace1.org/"> <pd_1:Name xmlns:pd="namespace2" xmlns:pd_1="http://namespace1.org/">A</pd_1:Name> <pd:Description xmlns:pd="namespace2">A1</pd:Description> </pd:Book> <pd:Book xmlns:pd="http://namespace1.org/"> <pd_1:Name xmlns:pd="namespace2" xmlns:pd_1="http://namespace1.org/">B</pd_1:Name> <pd:Description xmlns:pd="namespace2">B1</pd:Description> </pd:Book> </root>
The only pace I would like the namespaces to appear is within the book node. Please see below
<?xml version="1.0"?> <root> <pd:Book xmlns:pd="http://namespace1.org/"> <pd:Name >A</pd:Name> <pd:Description>A1</pd:Description> </pd:Book> <pd:Book xmlns:pd="http://namespace1.org/"> <pd:Name>B</pd_1:Name> <pd:Description>B1</pd:Description> </pd:Book> </root>
-
lightonphiri almost 13 years@polishchuk: Thank you for your response. Input XML is linked to too many nodes... for now though, you could assume that we are processing code under Update #1 above. I only need pointers on how to go about explicitly including namespaces to elements.
-
Kirill Polishchuk almost 13 yearsThere is no difference for XML engine where namespace is defined. You can define namespace in root node
<root xmlns:pd="namespace2">
or in book node<pd:Book xmlns:pd="namespace2">
. Both are equals for XML parser.
-
-
lightonphiri almost 13 yearsThank you for the response; I actually tried that. However, what I want is for the namespaces to appear in one of the inner nodes --say the Book element in this case and not the root. How to I explicitly dell xslt that? Your solution by default puts the namespace declarations in the root node. Remember I will have multiple xml files each of which is supposed to have the same namespace declarations defined.
-
lightonphiri almost 13 yearsThank you. Is there a particular reason why I should point the same prefix to two different namespaces? I need to understand so I can properly replicate the solutiion. xmlns:pd="namespace2" xmlns:bd="namespace1"
-
Kirill Polishchuk almost 13 years@phiri, You can omit prefixes. Simply write
<Book xmlns="namespace1">
. -
Kirill Polishchuk almost 13 years@phiri, It is not necessary. In other words, prefix it is like alias, no more.
-
lightonphiri almost 13 yearsbut when I remove it, it messes up the resulting xml. I get the error below when I removed the namespace delaration in the stylesheet node. stackoverflow.xsl:24: namespace error : Namespace prefix pd on Description is not defined <pd:Description>
-
lightonphiri almost 13 yearsThank you for helping; however, your recent solution does not have prefixes and when I included them, inner nodes that are not supposed to have namespace declarations are explicitly generated with the namespace. Can you manage to move this discussion to chat?
-
Kirill Polishchuk almost 13 years@phiri, Well... Can you provide abstract input XML and desired output XML, so I can understand your needs...?
-
Kirill Polishchuk almost 13 years@phiri, Write here, so other people can help you. Don't forget to remove your comment with contacts.
-
lightonphiri almost 13 yearszikomo kwambili (Thank you very much) --explicitly embedding the namespaces works fine now.