You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2004/06/02 06:04:25 UTC

DO NOT REPLY [Bug 23955] - unique attributes with same qname conflict resolution is incorrect

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=23955>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=23955

unique attributes with same qname conflict resolution is incorrect





------- Additional Comments From minchau@ca.ibm.com  2004-06-02 04:04 -------
Here is the original more or less:
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 foo:attr="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
        </elem2>
    </elem1>
</xsl:template>

elem1 has the namespace mapping (or node)  "foo"-> "bar1".  In the construction 
of elem2 this mapping or node is inherited so elem2 has the same namespace 
node "foo" -> "bar1".  Then we add an attribute (the <xsl:attribute...>) This 
xsl:attribute element is the name "foo:attr" but with "foo" mapping to "bar2".  
Now during the construction of elem2 we have a collision  ... ouch.

Here is what happens for Xalan-J interpretive during its construction:
1 - element "elem1" exists at depth 1
2 - startPrefixMaping call . . . but this is the kind after the element name 
(unlike classical SAX call) "foo" maps to "bar1" so this mapping applies to 
elem1 and all children of elem1
3 - element "elem2", child of "elem1" exists at depth 2
4 - the current element "elem2" has an attribute of foo:attr="1"  (.... 
serializer checks out if "foo" maps to anything, ... it does ... a mapping for 
it exists at depth 1 things are looking good)
5 - add a namespace mapping for elem2 at depth 2,  "foo" maps to "bar2"  ( 
serializer dutifully over-rides the "foo" mapping of the parent that would 
otherwise be inherited)
6 - add an attribute to the current element "elem2" namely foo:attr="" is added 
to elem2  (.... serializer checks out if "foo" maps to anything, ... it 
does ... a mapping for it exists at depth 2 things are looking good ... well 
not really)


The output should look something like this:
Here is the original more or less:
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 foo:attr="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
        </elem2>
    </elem1>
</xsl:template>

elem1 has the namespace node  "foo"-> "bar1".  In the construction of elem2 
this mapping or node is inherited so elem2 has the same namespace node "foo" -
> "bar1".  Then we add an attribute (the <xsl:attribute...>) This xsl:attribute 
element is the name "foo:attr" but with "foo" mapping to "bar2".  Now during 
the construction of elem2 we have a collision  ... ouch.

The serializer is not at fault.  Here is what it is told from Xalan-J 
interpretive during its construction:
1 - element "elem1" exists at depth 1
2 - oh yah, I forgot to mention a startPrefixMaping call . . . but this is the 
kind that I tell you about after I told you about the element name (unlike 
classical SAX call) "foo" maps to "bar1"
3 - element "elem2" exits at depth 2
4 - the current element "elem2" has an attribute of foo:attr="1"  (.... 
serializer checks out if "foo" maps to anything, ... it does ... a mapping for 
it exists at depth 1 things are looking good)
5 - oh yah, I forgot to mention a prefix mapping for elem2 at depth 2,  "foo" 
maps to "bar2"  ( serializer dutifully over-rides the "foo" mapping)
6 - the current element "elem2" has an attibute of foo:attr=""   (.... 
serializer checks out if "foo" maps to anything, ... it does ... a mapping for 
it exists at depth 2 things are looking good ... well not really)


The output should look something like this:
<elem1 xmlns:foo="bar1">
<elem2 foo:attr="1" xmlns:ns0="bar2" ns0:attr=""/></elem1>


Initally I thought that if prefix "foo" hadn't been used on line 3 (<!-- line 
3 -->) that I would use the prefix "foo" on line 4.  For example if the 
stylesheet were:
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
        </elem2>
    </elem1>
</xsl:template>

Then the output would be:
<elem1 xmlns:foo="bar1"><elem2 xmlns:foo="bar2"  foo:attr="" attr1="1" 
></elem2></elem1>

But initially the namespace node ("foo" maps to "bar2") applies only to the 
attribute, during construction the attribute gets hoisted up from being a child 
element of elem2 to being on the same footing as other attributes that elem2 
and in doing so this namespace mapping gets more exposed.  Due to the 
inheritance of namespace nodes in serialized XML documents and due to not being 
able to un-declare such mappings, this example would be problematic:

<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
           <elem3 foo:att3="3" />
        </elem2>
    </elem1>
</xsl:template>

The namespace node on line 4 should now not be exposed when attibutes are 
colleced for elem2, because this mapping of "foo" to "bar2" would mask the one 
on line 2 and elem3 would not inherit the right mapping.

The serializer runs on the fly and doesn't know if elem3 (or deeper children) 
are comming or not, or whether they might use the prefix "foo" or not.  So my 
conclusion is that during such construction, if the prefix mapping already 
exists and is to the same URI then use the prefix, e.g.
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar1"/> <!-- line 4 -->
           <elem3 foo:att3="3" />
        </elem2>
    </elem1>
</xsl:template>

and output this:
<elem1 xmlns:foo="bar1"><elem2 foo:attr="" attr1="1" ><elem3 
foo:attr3="3" /></elem2></elem1>

but otherwise do not use the prefix from the name in the xsl:attribute element 
at all because it will pollute the namespace mappings.

Initally I thought that if prefix "foo" hadn't been used on line 3 (<!-- line 
3 -->) that I would use the prefix "foo" on line 4.  For example if the 
stylesheet were:
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
        </elem2>
    </elem1>
</xsl:template>

Then the output would be:
<elem1 xmlns:foo="bar1"><elem2 xmlns:foo="bar2"  foo:attr="" attr1="1" 
></elem2></elem1>

But initially the namespace node ("foo" maps to "bar2") applies only to the 
attribute, during construction the attribute gets hoisted up from being a child 
element of elem2 to being on the same footing as other attributes that elem2 
and in doing so this namespace mapping gets more exposed.  Due to the 
inheritance of namespace nodes in serialized XML documents and due to not being 
able to un-declare such mappings, this example would be problematic:

<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar2"/> <!-- line 4 -->
           <elem3 foo:att3="3" />
        </elem2>
    </elem1>
</xsl:template>

The namespace node on line 4 should now not be exposed when attibutes are 
colleced for elem2, because this mapping of "foo" to "bar2" would mask the one 
on line 2 and elem3 would not inherit the right mapping.

The serializer runs on the fly and doesn't know if elem3 (or deeper children) 
are comming or not, or whether they might use the prefix "foo" or not.  So my 
conclusion is that during such construction, if the prefix mapping already 
exists and is to the same URI then use the prefix, e.g.
<xsl:template match="/">
    <elem1 xmlns:foo="bar1">
        <elem2 attr1="1">   <!-- line 3 -->
            <xsl:attribute name="foo:attr" xmlns:foo="bar1"/> <!-- line 4 -->
           <elem3 foo:att3="3" />
        </elem2>
    </elem1>
</xsl:template>

and output this:
<elem1 xmlns:foo="bar1"><elem2 foo:attr="" attr1="1" ><elem3 
foo:attr3="3" /></elem2></elem1>

XSLTC may be a different story.

- Brian Minchau

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-dev-help@xml.apache.org