You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by "Ushakov, Sergey N" <us...@int.com.ru> on 2002/05/05 14:54:46 UTC

issue: namespace not declared and DOCTYPE present

Hello,

I've run into a problem with processing ready-made XML documents. Namely, I
have to modify some data contained in SVG images produced by Corel Draw.

The issue is that the input document does not have any namespace declaration
and has a DOCTYPE present. With this data on input I cannot match any
element with its tagname. The only catch that matches anything is node(),
but it is not the best way to program XSL...

If I remove the DOCTYPE declaration from the source document - then
everything is ok, and any element is matched with its tagname without any
namespace prefix. If I do not remove DOCTYPE - nothing helps, and I could
not find a combination of namespace declaration in the stylesheet that would
work.

There is a strange thing about the resulting document - it has a namespace
declaration inside, but a weird one:
<svg xmlns="%SVGNamespace;" ... >

Another strange thing is that if I make a dump of input data using
match="node()" and then examining name(), local-name() and namespace-uri() -
namespace-uri is shown as empty. And still matching by tagname does not
work.

Any ideas? What is wrong - me, Corel or Xalan ? :)
Is it a case for studying XSL programming or filing a Xalan bug? :)

Sample SVG file is attached.

Regards,
Sergey

Re: issue: namespace not declared and DOCTYPE present

Posted by "Ushakov, Sergey N" <us...@int.com.ru>.
Peter, thank you for your prompt response.

I suspected it is a FAQ... :)  I have even noticed and followed the recent
posting by Dave Bertoni regarding similar issue...

The problem is that the construct you propose _should_ work (i believe) but
does _not_ in fact work. At least for me... :)

Please find appended the template i have made that declares the svg
namespace. Unfortunately it does not match... Or maybe i miss something
evident... ?

Can the problem be somehow related to the fact that Xalan has to handle
nested DTDs in this case? I suspect that Xalan somehow fails to resolve the
"SVGNamespace" entity...

I have checked the dump test cases once again. The namespace-uri() is empty
(or null?) in all cases (with DOCTYPE both retained and removed).

If you are in a position to look into the matter i can mail my other test
cases to you. I'm not sure it is good to post all this stuff on the list...

Best regards,
Sergey

----- Original Message -----
From: "Peter Davis" <pe...@pdavis.cx>
To: "Ushakov, Sergey N" <us...@int.com.ru>
Cc: <xa...@xml.apache.org>
Sent: Sunday, May 05, 2002 9:46 PM
Subject: Re: issue: namespace not declared and DOCTYPE present


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sunday 05 May 2002 05:54, Ushakov, Sergey N wrote:
> Hello,
>
> I've run into a problem with processing ready-made XML documents. Namely,
I
> have to modify some data contained in SVG images produced by Corel Draw.
>
> The issue is that the input document does not have any namespace
> declaration and has a DOCTYPE present. With this data on input I cannot
> match any element with its tagname. The only catch that matches anything
is
> node(), but it is not the best way to program XSL...
>[out of order]
> There is a strange thing about the resulting document - it has a namespace
> declaration inside, but a weird one:
> <svg xmlns="%SVGNamespace;" ... >


If you look at the DTD that is imported by the document (after resolving the
entities), you will see

<!ATTLIST svg
  xmlns CDATA #FIXED "%SVGNamespace;"
  ...
>

in svg-20000303-shared.dtd.  This defines a default value for the "xmlns"
attribute on the <svg> element to the value defined in the original DTD:

<!ENTITY % SVGNamespace "http://www.w3.org/2000/svg-20000303-stylable" >

When your document uses the DTD, even though no xmlns is defined in the
document, the document defines it to
"http://www.w3.org/2000/svg-20000303-stylable".

The problem is that this is the *default* namespace (as opposed to a
namespace
attached to a prefix).  Note that this is a very very FAQ.  You can find
tons
of information elsewhere if I don't make sense :)

Anyway, the problem is that a stylesheet like this:

<xsl:stylesheet xmlns:xsl="..."
xmlns="http://www.w3.org/2000/svg-20000303-stylable">
  <xsl:template match="svg"> ... </xsl:template>
</xsl:stylesheet>

does *not* match the <svg> element defined in the SVG namespace.  It matches
the <svg> element with *no* namespace.  Basically, while XPath honors
namespace prefixes in match/select expressions, it ignores the default
namespace.

The solution is to assign the SVG namespace to a prefix.  What you want is
this:

<xsl:stylesheet xmlns:xsl="..."
xmlns:svg="http://www.w3.org/2000/svg-20000303-stylable">
  <xsl:template match="svg:svg"> ... </xsl:template>
</xsl:stylesheet>

You then have to replace *all* the places in your stylesheet where you
attempt
to match/select an SVG element with "svg:foo" instead of just "foo".  Note
that you do *not* need to change the source document for this to work; the
elements in the source document are declared in the SVG namespace so their
prefix or lack of prefix is irrelevent as long as the XPath expressions
match
elements in the same namespace.

Hopefully this will answer all your other questions if you think about it.

> If I remove the DOCTYPE declaration from the source document - then
> everything is ok, and any element is matched with its tagname without any
> namespace prefix. If I do not remove DOCTYPE - nothing helps, and I could
> not find a combination of namespace declaration in the stylesheet that
> would work.
>

If you remove the DOCTYPE declaration, like you did, then the default value
for "xmlns" is not defined by the DTD, and so the existing XPath expressions
are able to match the elements in the default namespace.  This is definitely
not the way to fix it.

> Another strange thing is that if I make a dump of input data using
> match="node()" and then examining name(), local-name() and namespace-uri()
> - namespace-uri is shown as empty.

It makes sense that name() would return a string without a prefix (since
there
is none), but not that namespace-uri() returns null.  Are you sure you did
this test before you removed the DTD?

> And still matching by tagname does not work.

Remember that XPath does *not* match "by tagname".  It matches by QName,
which
is a combination of the URI associated with a tag's prefix combined with its
local-name.  The prefix or lack of prefix is not part of the equation, only
the URI defined with xmlns is used.  Again remember that when an element
does
not have a prefix but xmlns=something, it still has a URI.

> Any ideas? What is wrong - me, Corel or Xalan ? :)
> Is it a case for studying XSL programming or filing a Xalan bug? :)

Some people consider this a bug in the XPath specification, but it is more
like a "feature" that just happens to confuse a *lot* of people :)  Things
are this way intentionally.

- --
Peter Davis
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE81W/fNSZCJx7tYycRArHPAKDfgvmakF+Dnqxf5Ehyzq5Ixg63LACgu7yw
XehkITPzllS6By/x4mBrxos=
=WkIe
-----END PGP SIGNATURE-----


Re: issue: namespace not declared and DOCTYPE present

Posted by Peter Davis <pe...@pdavis.cx>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sunday 05 May 2002 05:54, Ushakov, Sergey N wrote:
> Hello,
>
> I've run into a problem with processing ready-made XML documents. Namely, I
> have to modify some data contained in SVG images produced by Corel Draw.
>
> The issue is that the input document does not have any namespace
> declaration and has a DOCTYPE present. With this data on input I cannot
> match any element with its tagname. The only catch that matches anything is
> node(), but it is not the best way to program XSL...
>[out of order]
> There is a strange thing about the resulting document - it has a namespace
> declaration inside, but a weird one:
> <svg xmlns="%SVGNamespace;" ... >


If you look at the DTD that is imported by the document (after resolving the 
entities), you will see

<!ATTLIST svg
  xmlns CDATA #FIXED "%SVGNamespace;"
  ...
>

in svg-20000303-shared.dtd.  This defines a default value for the "xmlns" 
attribute on the <svg> element to the value defined in the original DTD:

<!ENTITY % SVGNamespace "http://www.w3.org/2000/svg-20000303-stylable" >

When your document uses the DTD, even though no xmlns is defined in the 
document, the document defines it to 
"http://www.w3.org/2000/svg-20000303-stylable".

The problem is that this is the *default* namespace (as opposed to a namespace 
attached to a prefix).  Note that this is a very very FAQ.  You can find tons 
of information elsewhere if I don't make sense :)

Anyway, the problem is that a stylesheet like this:

<xsl:stylesheet xmlns:xsl="..." 
xmlns="http://www.w3.org/2000/svg-20000303-stylable">
  <xsl:template match="svg"> ... </xsl:template>
</xsl:stylesheet>

does *not* match the <svg> element defined in the SVG namespace.  It matches 
the <svg> element with *no* namespace.  Basically, while XPath honors 
namespace prefixes in match/select expressions, it ignores the default 
namespace.

The solution is to assign the SVG namespace to a prefix.  What you want is 
this:

<xsl:stylesheet xmlns:xsl="..." 
xmlns:svg="http://www.w3.org/2000/svg-20000303-stylable">
  <xsl:template match="svg:svg"> ... </xsl:template>
</xsl:stylesheet>

You then have to replace *all* the places in your stylesheet where you attempt 
to match/select an SVG element with "svg:foo" instead of just "foo".  Note 
that you do *not* need to change the source document for this to work; the 
elements in the source document are declared in the SVG namespace so their 
prefix or lack of prefix is irrelevent as long as the XPath expressions match 
elements in the same namespace.

Hopefully this will answer all your other questions if you think about it.

> If I remove the DOCTYPE declaration from the source document - then
> everything is ok, and any element is matched with its tagname without any
> namespace prefix. If I do not remove DOCTYPE - nothing helps, and I could
> not find a combination of namespace declaration in the stylesheet that
> would work.
> 

If you remove the DOCTYPE declaration, like you did, then the default value 
for "xmlns" is not defined by the DTD, and so the existing XPath expressions 
are able to match the elements in the default namespace.  This is definitely 
not the way to fix it.

> Another strange thing is that if I make a dump of input data using
> match="node()" and then examining name(), local-name() and namespace-uri()
> - namespace-uri is shown as empty.

It makes sense that name() would return a string without a prefix (since there 
is none), but not that namespace-uri() returns null.  Are you sure you did 
this test before you removed the DTD?

> And still matching by tagname does not work.

Remember that XPath does *not* match "by tagname".  It matches by QName, which 
is a combination of the URI associated with a tag's prefix combined with its 
local-name.  The prefix or lack of prefix is not part of the equation, only 
the URI defined with xmlns is used.  Again remember that when an element does 
not have a prefix but xmlns=something, it still has a URI.

> Any ideas? What is wrong - me, Corel or Xalan ? :)
> Is it a case for studying XSL programming or filing a Xalan bug? :)

Some people consider this a bug in the XPath specification, but it is more 
like a "feature" that just happens to confuse a *lot* of people :)  Things 
are this way intentionally.

- -- 
Peter Davis
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE81W/fNSZCJx7tYycRArHPAKDfgvmakF+Dnqxf5Ehyzq5Ixg63LACgu7yw
XehkITPzllS6By/x4mBrxos=
=WkIe
-----END PGP SIGNATURE-----