如何使用XMLStreamReader读取xml中的命名空间?

时间:2014-08-05 09:24:51

标签: java xml stax xmlstreamreader

我有一个xml文件,我使用XMLStreamReader对象从中读取。 所以我会保持简单:

让我们来看看这个xml示例:

<mySample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attribute1="value1"/>

所以我需要的是获取值(作为字符串)&#34; xmlns:xsi&#34;并获得值(也作为字符串)&#34; http://www.w3.org/2001/XMLSchema-instance&#34;

我确实尝试过这样的测试:

if (reader.getEventType() != XMLStreamConstants.NAMESPACE){
       attributeName = reader.getAttributeLocalName(i);
       attributeValue = reader.getAttributeValue(i);
}
else{
       attributeName = reader.getNamespacePrefix(i) + reader.getNamespaceURI(i);
       attributeValue = reader.getAttributeValue(i);
}

但它不起作用。

显然我错过了这个API的新手,所以任何帮助都会非常受欢迎。

1 个答案:

答案 0 :(得分:6)

JSR-173规范(Stax API for Java)声明了以下关于NAMESPACE事件:

  

<强>命名空间
  命名空间声明也可以存在于StartElement之外,并且可以报告为a   独立信息项。 通常,命名空间是作为StartElement的一部分报告的   事件。当命名空间是XQuery或XPath表达式的结果时,它们可能就是   报告为独立事件。

因此,如果您正在查看命名空间事件,则最有可能检查StartElement事件并检查它们。再次,从规范:

  

可以使用以下方法访问命名空间:

     
    

int getNamespaceCount();
    String getNamespacePrefix(int index);
    String getNamespaceURI(int index);

  
     

只有当前StartElement上声明的名称空间可用。列表的确如此   不包含以前声明的命名空间,也不删除重新声明的命名空间。

在解析过程中的任何时候,您都可以获得当前完整的命名空间上下文:

  

通过调用可以获得当前状态的名称空间上下文   XMLStreamReader.getNamespaceContext()或   StartElement.getNamespaceContext()。这些方法返回一个实例   javax.xml.namespace.NamespaceContext界面。

该理论:大多数名称空间声明来自START_ELEMENT,有些可能是独立的。

实际上,从文件中读取时,我从未遇到API报告的NAMESPACE事件。它几乎总是作为START_ELEMENT的一部分报告(并在相应的END_ELEMENT中重复),因此如果您对名称空间声明感兴趣,则必须检查START_ELEMENT。例如,从您的文档开始:

String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><mySample xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" attribute1=\"value1\"/>";
XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(new StringReader(xml));
while (reader.hasNext()) {
  int event = reader.next();
  if (XMLStreamConstants.START_ELEMENT == event) {
    if (reader.getNamespaceCount() > 0) {
      // This happens
      System.out.println("ELEMENT START: " + reader.getLocalName() + " , namespace count is: " + reader.getNamespaceCount());
      for (int nsIndex = 0; nsIndex < reader.getNamespaceCount(); nsIndex++) {
        String nsPrefix = reader.getNamespacePrefix(nsIndex);
        String nsId = reader.getNamespaceURI(nsIndex);
        System.out.println("\tNamepsace prefix: " + nsPrefix + " associated with URI " + nsId);
      }
    }
  } else if(XMLStreamConstants.NAMESPACE == event) {
    // This almost never happens
    System.out.println("NAMESPACE EVENT");
  }
}

将产生:

  

ELEMENT START:mySample,名称空间计数为:1

     
    

Namepsace前缀:与URI http://www.w3.org/2001/XMLSchema-instance

关联的xsi   

结论:您应该检查NAMESPACE和START_ELEMENT事件,即使大多数情况下,您只会有START_ELEMENT报告命名空间声明,它不是一个或另一个,它们都是。