我有一个xml文档
<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>
其中b:Button是cont:component
的xml扩展类型在我的startElement调用中,我按预期收到了一个http://mebigfatguy.com/ds/container的uri和cont:component的qname。 xsi:type =“b:Button”可以在属性中找到,也可以按预期找到。
我遇到的问题是如何从xsi:type属性中检索b:Button的名称空间uri。我是否必须自己手动管理xmlns属性?或者是否有内置的方法来解决uri是什么?
答案 0 :(得分:2)
SAX报告ContentHandler.startElement
中元素和属性的名称空间URI,但没有提供在解析过程中将前缀转换为名称空间URI的一般方法。
为此,您必须在startPrefixMapping
中实施endPrefixMapping
和ContentHandler
,并跟踪活动绑定。 (如果做得对,这还必须涵盖名称空间未声明)。
答案 1 :(得分:0)
是。您必须为b:Button
执行查找命名空间uri,并且必须使用org.xml.sax.helpers.NamespaceSupport管理xmlns属性。正确填充NamespaceSupport
有点棘手。
以下是使用xsi:type
和uri
打印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();
}
}
这是驱动程序功能:
public static void main(String[] args) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.newSAXParser().parse("test.xml", new XSIHandler());
}
输出是:
xsi:type for cont:component is uri: http://mebigfatguy.com/ds/button localName: Button