I have an xml document as
<fr:frame xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:fr="http://mebigfatguy.com/ds/frame"
xmlns:comp="http://mebigfatguy.com/ds/component"
xmlns:cont="http://mebigfatguy.com/ds/container"
xmlns:b="http://mebigfatguy.com/ds/button">
<comp:preferredSize>500,300</comp:preferredSize>
<cont:childComponent>
<cont:name>CENTER</cont:name>
<cont:component xsi:type="b:Button">
<comp:name>Click Me</comp:name>
</cont:component>
</cont:childComponent>
<fr:title>Example</fr:title>
</fr:frame>
where b:Button is an xml extension type of cont:component
In my startElement call, i receive a uri of http://mebigfatguy.com/ds/container and qname of cont:component as expected. The xsi:type="b:Button" is found in the attributes, also as expected.
The question I have is how does one lookup the namespace uri of b:Button as retrieved from the xsi:type attribute. Do i have to manage the xmlns attributes manually myself? or is there a built in way to resolve what the uri is?
Yes. you have to do lookup namespace uri for b:Button
and you have to manage xmlns attributes using org.xml.sax.helpers.NamespaceSupport. It is little tricky to populate NamespaceSupport
properly.
Below is the sample code which prints xsi:type
value with uri
and localname
:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.NamespaceSupport;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParserFactory;
/**
* @author Santhosh Kumar Tekuri
*/
public class XSIHandler extends DefaultHandler{
private boolean needNewContext;
private NamespaceSupport nsSupport;
@Override
public void startDocument() throws SAXException{
nsSupport = new NamespaceSupport();
needNewContext = true;
super.startDocument();
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException{
if(needNewContext){
nsSupport.pushContext();
needNewContext = false;
}
nsSupport.declarePrefix(prefix, uri);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException{
if(needNewContext)
nsSupport.pushContext();
needNewContext = true;
String xsiType = atts.getValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
if(xsiType!=null){
String prefix, suffix;
int colon = xsiType.indexOf(':');
if(colon==-1){
prefix = "";
suffix = xsiType;
}else{
prefix = xsiType.substring(0, colon);
suffix = xsiType.substring(colon+1);
}
System.out.println("xsi:type for " + qName + " is uri: " + nsSupport.getURI(prefix) + " localName: " + suffix);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException{
nsSupport.popContext();
}
}
here is the driver function:
public static void main(String[] args) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.newSAXParser().parse("test.xml", new XSIHandler());
}
the output is:
xsi:type for cont:component is uri: http://mebigfatguy.com/ds/button localName: Button