Re: cannot find the namespace declarations from an extension function

Adrian Herscu <[email protected]>
Newsgroups gmane.text.xml.xalan.java.user
Message-ID <[email protected]>
I think that I have found an workaround :)
Instead of applying the transformation on a StreamSource object I am 
applying it on a DOMSource object and now the lookupNamespaceUri method 
works as expected.
Adrian.

Adrian Herscu wrote:
> Hi Michael and thanks for the response.
> Please see my comments between your lines.
> Regards,
> Adrian.
> 
> Michael Ludwig wrote:
> 
>>>     <gen:test func="lookupNamespaceUri">
>>
>> Now what's wrong with <xsl:value-of select="namespace-uri()"/> ?
>> No need to call an extension function here.
>>
>> To get the URIs for all the namespace nodes in scope, try:
>>
>>     <xsl:for-each select="namespace::node()">
>>       <NS><xsl:value-of select="."/></NS>
>>     </xsl:for-each>
>>
> 
> Please remember that this is just a simplified test case. My actual 
> problem is traversing relational data structures with less XSL code.
>  From the initial post:
> 
> <!-- key for looking up the wsdl:binding -->
> <variable name="binding-key">
>   <apply-templates select="." mode="binding-key" />
> </variable>
> 
> <for-each select="key('binding',$binding-key)">
> ...
> </for-each>
> 
> (this also requires some infrastructure code -- the definitions for the 
> keys and the templates; and these definitions are required for each 
> relational structure in the input model, so it is very easy to mess 
> things around resulting in hours of debugging)
> 
> Instead of that I was looking for an extension function that will enable 
> me to write something like that:
> <for-each select="myxslutils:ref(/wsdl:definitions/wsdl:binding,
>   'name', @binding, /wsdl:definitions/@targetNamespace)">
> ...
> </for-each>
> 
>>>       <!-- PROBLEM: works for 'wsdl' prefix,
>>>            for 'tns' and everything else,
>>>            e.g. 'soap', 'xsd', etc., returns null
>>>            -->
>>>       <value-of select="myext:lookupNamespaceUri(current(), 'tns')" />
>>
>> Note you don't need current() here, although there is no harm in doing
>> so. The current() function is used to get the context node *outside* an
>> XPath expression from inside that expression when moving away from the
>> context node, which you're not doing. So you can just use ".", the dot,
>> which is the context node (or context item in XSLT 2.0).
>>
>>>     public static String lookupNamespaceUri(final Node currentNode,
>>>             final String prefix) {
>>>         final String namespaceUri;
>>>
>>>         namespaceUri =
>>>             currentNode.getOwnerDocument().getDocumentElement()
>>>                 .lookupNamespaceURI(prefix);
>>>
>>>         return namespaceUri;
>>>     }
>>
>> I don't know why this doesn't return the expected result. A call to
>> getNodeName() works just fine.
>>
>> But then, maybe the expectation is wrong. An XSLT 1.0 processor isn't
>> obliged to respect your choice of prefixes for namespaces,
> 
> Hmmm... It appears that the parser completely ignores all 'xmlns' 
> attributes. The interesting thing is that it reads attributes from other 
> non-null namespaces.
> 
> Try to add a breakpoint on 
> http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/dtm/ref/DTMNodeProxy.java?view=markup 
> 
> line #1643
> 
>     public String lookupNamespaceURI(String specifiedPrefix) {
>     ...
>                 if (this.hasAttributes()) {
>                     NamedNodeMap map = this.getAttributes();
>                     int length = map.getLength();
>                     for (int i=0;i<length;i++) {
>     ...
> map.getLength returns 1 as if the 'targetNamespace' was the only 
> attribute. Tried to add
>   xmlns:foo="123"
>   foo:dummy="abc"
> to the wsdl:definitions and now the map.getLength returns 2 and the 
> foo:dummy attribute node node is recognized correctly.
> 
> 
> I tested this behavior with the Xerces parser, here is the test class:
> 
> package com.acme.apps;
> 
> import java.io.File;
> import java.io.IOException;
> 
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import javax.xml.parsers.ParserConfigurationException;
> 
> import junit.framework.TestCase;
> 
> import org.w3c.dom.Document;
> import org.w3c.dom.Element;
> import org.xml.sax.SAXException;
> 
> public class XmlOperationsTest
>         extends TestCase {
> 
>     private static final String TEST_ROOT_DIR = "target/test-classes";
> 
>     private static final String TEST_XML =
>         "com/acme/apps/convert-temperature-service.wsdl";
> 
>     private static final File TEST_XML_FILE =
>         new File(TEST_ROOT_DIR, TEST_XML);
> 
>     public final void testLookupNamespaceUri()
>             throws ParserConfigurationException, SAXException,
>             IOException {
>         final DocumentBuilderFactory dbf =
>             DocumentBuilderFactory.newInstance();
>         dbf.setNamespaceAware(true);
>         final DocumentBuilder db = dbf.newDocumentBuilder();
>         final Document xml = db.parse(TEST_XML_FILE);
>         final Element documentElement = xml.getDocumentElement();
> 
>     /* NOTE: stepping inside the implementation of the method below
>     reveals that the 'xmlns:' prefixed attributes are counted as the
>     rest of attributes, which is different than the Xalan's parser
>     behavior. Therefore, I think this is a bug in Xalan. */
> 
>         final String tnsUri = documentElement.lookupNamespaceURI("tns");
> 
>         System.out.println(tnsUri);
> 
>         assertEquals("http://www.webserviceX.NET/", tnsUri);
>     }
> }
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.