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

mah*_*lkh 2 java xml stax xmlstreamreader

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

我们来看看这个xml示例:

<mySample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attribute1="value1"/>
Run Code Online (Sandbox Code Playgroud)

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

我确实试过这样的测试:

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);
}
Run Code Online (Sandbox Code Playgroud)

但它没有用.

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

GPI*_*GPI 6

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

命名
空间命名空间声明也可以存在于StartElement之外,并且可以作为独立信息项报告.通常,命名空间是作为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");
  }
}
Run Code Online (Sandbox Code Playgroud)

会产生:

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

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

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