You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by Eric Heath <eh...@interchange.ubc.ca> on 2002/10/08 05:14:16 UTC
Xerces NS Declarations and Canonicalization
Hi,
I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2
to write
out the canonical form of an XML document using
org.apache.xml.security.c14n.Canonicalizer
(specifically the implementation for
http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
suppose).
I'm having a problem in that my XML document's namespace declarations
are not being
displayed in the canonical format in a certain scenario.
When I use the javax.xml.parsers.DocumentBuilderFactory,
javax.xml.parsers.DocumentBuilder dynamic duo to create a new document via
DocumentBuild.newDocument() I get back a org.apache.xerces.dom.DocumentImpl
just as expected.
Now I build up this Document including some elements that contain
namespace declarations,
no big deal.
Finally use Canonicalizer to canonicalize my DOM with
Canonicalizer.canonicalizeSubtree(domDoc)
and the namespace declarations are *not* shown in the output! <-- This
is my problem.
If, on the other hand, I read in an existing document I get back an
object typed as
org.apache.xerces.dom.DeferredDocumentImpl and the canonical form of
this DOM has the NS
declarations included (like I want).
I've done a little searching around, but haven't run into any solutions
for this problem. Any ideas
on why the NS declarations would be omitted from the canonical form when
I start from an empty
Document?
Regards,
Eric
Re: Xerces NS Declarations and Canonicalization
Posted by Eric Heath <eh...@interchange.ubc.ca>.
Christian Geuer-Pollmann wrote:
> Hi Eric,
>
> now I know what the problem is. First how it works, then why:
>
> Element rootElement =
> domDocument.createElementNS("http://myNamespaceURI",
> "nsPrefix:elementName");
>
> // you have to *manually* add the namespace
> // definition attribute here:
> rootElement.setAttributeNS(
> "http://www.w3.org/2000/xmlns/",
> "xmlns:nsPrefix",
> "http://myNamespaceURI");
>
> Why: The XMLSerializer from Xerces is so gently to traverse the document
> and add namespace attributes whereever needed. XMLUtils (which is called
> internally before c14n) doesn't do this at the moment. So the below code
> goes to c14nize a tree which in fact *has* no namespace attribute at
> that point. But we can change the XMLUtils#circumventBug2650 method so
> that it also adds this stuff.
>
> Christian
>
That would probably be a nice feature. Thanks for the insight.
I think I was just unsure of the behaviour of the Canonicalizer because
I have two
cases in my code:
1) The situation that is illustrated in my example below where I start
from an empty
Document.
2) Similar to my example, except that I use DocumentBuilder.parse(...)
to create the DOM
Document.
- In this case SAX probably creates the namespaces as attributes
as I do
see them in the c14n output.
Thanks again,
Eric
>
>
> --On Tuesday, October 08, 2002 11:54 AM -0700 Eric Heath
> <eh...@interchange.ubc.ca> wrote:
>
>> The actual sign/verify process works correctly for me, I just have a
>> problem displaying the DOM in canonical form.
>>
>> Here's some code that hopefully illustrates my problem:
>>
>> import java.io.*;
>>
>> import javax.xml.parsers.DocumentBuilder;
>> import javax.xml.parsers.DocumentBuilderFactory;
>> import org.w3c.dom.Document;
>> import org.w3c.dom.Element;
>>
>> import org.apache.xml.security.c14n.Canonicalizer;
>> import org.apache.xml.serialize.XMLSerializer;
>> import org.apache.xml.serialize.OutputFormat;
>>
>> public class Test
>> {
>> public static void main(String[] args)
>> {
>> final String CANONICALIZATION_METHOD =
>> "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
>>
>> try
>> {
>> // Construct an empty DOM document
>> DocumentBuilderFactory docBuilderFactory =
>> DocumentBuilderFactory.newInstance();
>> docBuilderFactory.setNamespaceAware(true);
>> DocumentBuilder docBuilder =
>> docBuilderFactory.newDocumentBuilder(); Document domDocument
>> = docBuilder.newDocument();
>>
>> // Create the root element and add it to the DOM
>> Element rootElement =
>> domDocument.createElementNS("http://myNamespaceURI",
>> "nsPrefix:elementName");
>> domDocument.appendChild(rootElement);
>>
>> // Add a child elements for flavour
>> Element childElement =
>> domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
>> rootElement.appendChild(childElement);
>>
>> // Get a Canonicalizer and write the canonical form of the
>> DOM to stdout Canonicalizer canonicalizer =
>> Canonicalizer.getInstance(CANONICALIZATION_METHOD); byte[]
>> buffer = canonicalizer.canonicalizeSubtree(domDocument);
>> System.out.println("Canonical form of DOM:");
>> System.out.println(new String(buffer));
>>
>> // Compare the output to the serialized version
>> ByteArrayOutputStream baos = new ByteArrayOutputStream();
>> OutputFormat outputFormat = new OutputFormat("XML", "UTF-8",
>> false); // false == no pretty printing XMLSerializer
>> xmlSerializer = new XMLSerializer(baos, outputFormat);
>> xmlSerializer.serialize(domDocument);
>> System.out.println("Serialized form of DOM:");
>> System.out.println(baos.toString());
>> }
>> catch (Throwable t)
>> {
>> t.printStackTrace(System.out);
>> }
>> }
>> }
>>
>> As you can see, the namespace declaration
>> xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical
>> form of the DOM.
>>
>> I hope this illustrates my problem a little more clearly.
>>
>> Cheers,
>> Eric
>>
>>
>>
>
>
>
Re: Xerces NS Declarations and Canonicalization
Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.
Hi Eric,
now I know what the problem is. First how it works, then why:
Element rootElement =
domDocument.createElementNS("http://myNamespaceURI",
"nsPrefix:elementName");
// you have to *manually* add the namespace
// definition attribute here:
rootElement.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns:nsPrefix",
"http://myNamespaceURI");
Why: The XMLSerializer from Xerces is so gently to traverse the document
and add namespace attributes whereever needed. XMLUtils (which is called
internally before c14n) doesn't do this at the moment. So the below code
goes to c14nize a tree which in fact *has* no namespace attribute at that
point. But we can change the XMLUtils#circumventBug2650 method so that it
also adds this stuff.
Christian
--On Tuesday, October 08, 2002 11:54 AM -0700 Eric Heath
<eh...@interchange.ubc.ca> wrote:
> The actual sign/verify process works correctly for me, I just have a
> problem displaying the DOM in canonical form.
>
> Here's some code that hopefully illustrates my problem:
>
> import java.io.*;
>
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import org.w3c.dom.Document;
> import org.w3c.dom.Element;
>
> import org.apache.xml.security.c14n.Canonicalizer;
> import org.apache.xml.serialize.XMLSerializer;
> import org.apache.xml.serialize.OutputFormat;
>
> public class Test
> {
> public static void main(String[] args)
> {
> final String CANONICALIZATION_METHOD =
> "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
>
> try
> {
> // Construct an empty DOM document
> DocumentBuilderFactory docBuilderFactory =
> DocumentBuilderFactory.newInstance();
> docBuilderFactory.setNamespaceAware(true);
> DocumentBuilder docBuilder =
> docBuilderFactory.newDocumentBuilder(); Document domDocument
> = docBuilder.newDocument();
>
> // Create the root element and add it to the DOM
> Element rootElement =
> domDocument.createElementNS("http://myNamespaceURI",
> "nsPrefix:elementName");
> domDocument.appendChild(rootElement);
>
> // Add a child elements for flavour
> Element childElement =
> domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
> rootElement.appendChild(childElement);
>
> // Get a Canonicalizer and write the canonical form of the
> DOM to stdout Canonicalizer canonicalizer =
> Canonicalizer.getInstance(CANONICALIZATION_METHOD); byte[]
> buffer = canonicalizer.canonicalizeSubtree(domDocument);
> System.out.println("Canonical form of DOM:");
> System.out.println(new String(buffer));
>
> // Compare the output to the serialized version
> ByteArrayOutputStream baos = new ByteArrayOutputStream();
> OutputFormat outputFormat = new OutputFormat("XML", "UTF-8",
> false); // false == no pretty printing XMLSerializer
> xmlSerializer = new XMLSerializer(baos, outputFormat);
> xmlSerializer.serialize(domDocument);
> System.out.println("Serialized form of DOM:");
> System.out.println(baos.toString());
> }
> catch (Throwable t)
> {
> t.printStackTrace(System.out);
> }
> }
> }
>
> As you can see, the namespace declaration
> xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical
> form of the DOM.
>
> I hope this illustrates my problem a little more clearly.
>
> Cheers,
> Eric
>
>
>
Re: Xerces NS Declarations and Canonicalization
Posted by Eric Heath <eh...@interchange.ubc.ca>.
The actual sign/verify process works correctly for me, I just have a
problem displaying the DOM in canonical form.
Here's some code that hopefully illustrates my problem:
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xml.serialize.OutputFormat;
public class Test
{
public static void main(String[] args)
{
final String CANONICALIZATION_METHOD =
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
try
{
// Construct an empty DOM document
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder =
docBuilderFactory.newDocumentBuilder();
Document domDocument = docBuilder.newDocument();
// Create the root element and add it to the DOM
Element rootElement =
domDocument.createElementNS("http://myNamespaceURI",
"nsPrefix:elementName");
domDocument.appendChild(rootElement);
// Add a child elements for flavour
Element childElement =
domDocument.createElementNS("http://myNamespaceURI", "nsPrefix:child1");
rootElement.appendChild(childElement);
// Get a Canonicalizer and write the canonical form of the
DOM to stdout
Canonicalizer canonicalizer =
Canonicalizer.getInstance(CANONICALIZATION_METHOD);
byte[] buffer = canonicalizer.canonicalizeSubtree(domDocument);
System.out.println("Canonical form of DOM:");
System.out.println(new String(buffer));
// Compare the output to the serialized version
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputFormat outputFormat = new OutputFormat("XML",
"UTF-8", false); // false == no pretty printing
XMLSerializer xmlSerializer = new XMLSerializer(baos,
outputFormat);
xmlSerializer.serialize(domDocument);
System.out.println("Serialized form of DOM:");
System.out.println(baos.toString());
}
catch (Throwable t)
{
t.printStackTrace(System.out);
}
}
}
As you can see, the namespace declaration
xmlns:nsPrefix="http://myNamespaceURI" is not displayed in the canonical
form of the DOM.
I hope this illustrates my problem a little more clearly.
Cheers,
Eric
Re: Xerces NS Declarations and Canonicalization
Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.
--On Tuesday, October 08, 2002 1:12 AM -0700 Eric Heath
<eh...@interchange.ubc.ca> wrote:
> Hi Christian,
>
> I poked around in the Apache XML Security source and it looks to me like
> namespaces are only processed in the DOM if they are represented as
> attributes during c14n canonicalization (let me know if I missed something
> in the canonicalization method).
I'm not sure whether I understand you correctly? When you sign (or verify)
a document, the namespaces are 'expanded' in
XMLUtils.circumventBug2650(Document). So there will be many namespace
'attributes' spreading over the document.
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650>
> It seems strange that the DeferredDocumentImpl converts namespace
> declarations to attribute format at some stage while the superclass
> DocumentImpl does not.
I really have a problem to understand what your problem is. Can you supply
source code which illustrates the problem?
> A work around on my end is to use JAXP's getNamespaceURI() and
> getNamespacePrefix() to manually add the namespace declarations as
> attributes, but doing this isn't the most graceful bit of code that I've
> had to write.
>
> I'm not sure what the history is behind DOM implementations supporting
> namespaces or if there is a standard anywhere that suggests that they
> represent namespace declarations as attributes, but it sure would be nice
> if the implementation of, say xerces, was consistent. :+)
>
> Would it be worth while for Apach XML Sec to also check the values of
> getNamespaceURI() and getNamespacePrefix() during canonicalization?
It does ;-))
Christian
Re: Xerces NS Declarations and Canonicalization
Posted by Eric Heath <eh...@interchange.ubc.ca>.
Hi Christian,
I poked around in the Apache XML Security source and it looks to me like
namespaces are only processed in the DOM if they are represented as
attributes during c14n canonicalization (let me know if I missed something
in the canonicalization method).
It seems strange that the DeferredDocumentImpl converts namespace
declarations to attribute format at some stage while the superclass
DocumentImpl does not.
A work around on my end is to use JAXP's getNamespaceURI() and
getNamespacePrefix() to manually add the namespace declarations as
attributes, but doing this isn't the most graceful bit of code that I've had
to write.
I'm not sure what the history is behind DOM implementations supporting
namespaces or if there is a standard anywhere that suggests that they
represent namespace declarations as attributes, but it sure would be nice
if the implementation of, say xerces, was consistent. :+)
Would it be worth while for Apach XML Sec to also check the values of
getNamespaceURI() and getNamespacePrefix() during canonicalization?
- Eric
Christian Geuer-Pollmann wrote:
> Hi Eric,
>
> I must admit that the only 'deeper' knowledge I have about Xerces is
> used in the IdResolver class where I register ID-type attributes in
> Xerces. At that class, I cast the Document to an
> org.apache.xerces.dom.DocumentImpl which works.
>
> DeferredDocumentImpl extends DocumentImpl
>
> Christian
>
>
> --On Monday, October 07, 2002 8:14 PM -0700 Eric Heath
> <eh...@interchange.ubc.ca> wrote:
>
>> Hi,
>>
>> I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2 to
>> write out the canonical form of an XML document using
>> org.apache.xml.security.c14n.Canonicalizer (specifically the
>> implementation for http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
>> suppose).
>>
>> I'm having a problem in that my XML document's namespace declarations are
>> not being displayed in the canonical format in a certain scenario.
>>
>> When I use the javax.xml.parsers.DocumentBuilderFactory,
>> javax.xml.parsers.DocumentBuilder dynamic duo to create a new document
>> via
>> DocumentBuild.newDocument() I get back a
>> org.apache.xerces.dom.DocumentImpl just as expected.
>>
>> Now I build up this Document including some elements that contain
>> namespace declarations, no big deal.
>>
>> Finally use Canonicalizer to canonicalize my DOM with
>> Canonicalizer.canonicalizeSubtree(domDoc) and the namespace declarations
>> are *not* shown in the output! <-- This is my problem.
>>
>> If, on the other hand, I read in an existing document I get back an
>> object typed as org.apache.xerces.dom.DeferredDocumentImpl and the
>> canonical form of this DOM has the NS declarations included (like I
>> want).
>>
>> I've done a little searching around, but haven't run into any solutions
>> for this problem. Any ideas on why the NS declarations would be omitted
>> from the canonical form when I start from an empty Document?
>>
>> Regards,
>> Eric
>
>
>
Re: Xerces NS Declarations and Canonicalization
Posted by Christian Geuer-Pollmann <ge...@nue.et-inf.uni-siegen.de>.
Hi Eric,
I must admit that the only 'deeper' knowledge I have about Xerces is used
in the IdResolver class where I register ID-type attributes in Xerces. At
that class, I cast the Document to an org.apache.xerces.dom.DocumentImpl
which works.
DeferredDocumentImpl extends DocumentImpl
Christian
--On Monday, October 07, 2002 8:14 PM -0700 Eric Heath
<eh...@interchange.ubc.ca> wrote:
> Hi,
>
> I have a project that uses xerces 2.0.1 and Apache XML Security 1.05D2 to
> write out the canonical form of an XML document using
> org.apache.xml.security.c14n.Canonicalizer (specifically the
> implementation for http://www.w3.org/TR/2001/REC-xml-c14n-20010315, I
> suppose).
>
> I'm having a problem in that my XML document's namespace declarations are
> not being displayed in the canonical format in a certain scenario.
>
> When I use the javax.xml.parsers.DocumentBuilderFactory,
> javax.xml.parsers.DocumentBuilder dynamic duo to create a new document via
> DocumentBuild.newDocument() I get back a
> org.apache.xerces.dom.DocumentImpl just as expected.
>
> Now I build up this Document including some elements that contain
> namespace declarations, no big deal.
>
> Finally use Canonicalizer to canonicalize my DOM with
> Canonicalizer.canonicalizeSubtree(domDoc) and the namespace declarations
> are *not* shown in the output! <-- This is my problem.
>
> If, on the other hand, I read in an existing document I get back an
> object typed as org.apache.xerces.dom.DeferredDocumentImpl and the
> canonical form of this DOM has the NS declarations included (like I want).
>
> I've done a little searching around, but haven't run into any solutions
> for this problem. Any ideas on why the NS declarations would be omitted
> from the canonical form when I start from an empty Document?
>
> Regards,
> Eric