XML:从 SAX 内容处理程序中的 xsi:type 属性查找名称空间 uri
XML: Finding namespace uri from xsi:type attribute in SAX content handler
我有一个 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 是什么?
SAX 报告 ContentHandler.startElement
中元素和属性的名称空间 URI,但不提供在解析期间将前缀转换为名称空间 URI 的通用方法。
为此,您必须在 ContentHandler
中实施 startPrefixMapping
和 endPrefixMapping
并跟踪活动绑定。 (如果做得好,这还必须涵盖名称空间未声明)。
是的。您必须为 b:Button
查找名称空间 uri,并且必须使用 org.xml.sax.helpers.NamespaceSupport 管理 xmlns 属性。正确填充 NamespaceSupport
有点棘手。
下面是使用 uri
和 localname
打印 xsi:type
值的示例代码:
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
我有一个 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 是什么?
SAX 报告 ContentHandler.startElement
中元素和属性的名称空间 URI,但不提供在解析期间将前缀转换为名称空间 URI 的通用方法。
为此,您必须在 ContentHandler
中实施 startPrefixMapping
和 endPrefixMapping
并跟踪活动绑定。 (如果做得好,这还必须涵盖名称空间未声明)。
是的。您必须为 b:Button
查找名称空间 uri,并且必须使用 org.xml.sax.helpers.NamespaceSupport 管理 xmlns 属性。正确填充 NamespaceSupport
有点棘手。
下面是使用 uri
和 localname
打印 xsi:type
值的示例代码:
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