XML命名空间默认/继承

ng.*_*ng. 6 java xml

在下面的XML片段中,a,c,d和e的命名空间是什么?请参阅文档或规范.

<a xmlns="http://domain/a">
    <pre:b xmlns:pre="http://domain/b">
        <c/>
        <d xmlns="">
            <e/>
        </d>
    </pre:b>
</a>
Run Code Online (Sandbox Code Playgroud)

此外,什么Java框架尊重官方名称空间默认?我已经删除了org.w2c.*DOM包,但它似乎没有正确解析名称空间URI?例如,具有类似功能的东西.

String namespace = DocumentParser.parse().
                    getElement("a").
                    getElement("b").
                    getElement("c").
                    getNamespaceURI();
Run Code Online (Sandbox Code Playgroud)

Mit*_*ers 12

据我所知,它将如下所示.

  • a将是http:// domain/a,因为它是默认命名空间
  • b将是http:// domain/b,因为它是b的已定义命名空间
  • c将是http:// domain/a,因为它是默认命名空间
  • 由于重命名命名空间,d将是空白/未设置的命名空间
  • e将是一个空白/未设置的命名空间,因为它嵌套在新的声明中

我的基础是这个规范.以下是帮助的摘要引用.

如果作用域中存在默认名称空间声明,则对应于未加前缀的元素名称的扩展名称将默认名称空间的URI作为其名称空间名称.如果作用域中没有默认名称空间声明,则名称空间名称没有值.未加前缀的属性名称的名称空间名称始终没有值.在所有情况下,本地名称都是本地部分(当然与未加前缀的名称本身相同).


Jon*_*eet 8

声明使用的名称空间将xmlns="..."成为其中任何元素的默认名称(当然,直到默认值在更深层元素中重新声明).所以你最终得到:

相关规范部分是XML名称规范,第6.2节:

默认命名空间声明的范围从它出现的start-tag的开头延伸到相应的end-tag的末尾,不包括任何内部默认命名空间声明的范围.对于空标记,范围是标记本身.

默认名称空间声明适用于其范围内的所有未加前缀的元素名称.默认名称空间声明不直接应用于属性名称; 对无前缀属性的解释由它们出现的元素决定.

如果作用域中存在默认名称空间声明,则对应于未加前缀的元素名称的扩展名称将默认名称空间的URI作为其名称空间名称.如果作用域中没有默认名称空间声明,则名称空间名称没有值.未加前缀的属性名称的名称空间名称始终没有值.在所有情况下,本地名称都是本地部分(当然与未加前缀的名称本身相同).


McD*_*ell 5

据我所知,Java中的所有标准XML API都支持名称空间.许多API是在命名空间创建之前编写的(或者变得流行 - 我再也记不住了).您经常需要启用支持:

public class NS {
  private static void print(Node node) {
    Queue<Node> nodes = new LinkedList<Node>();
    nodes.add(node);
    while (!nodes.isEmpty()) {
      node = nodes.poll();
      NodeList list = node.getChildNodes();
      for (int i = 0; i < list.getLength(); i++) {
        nodes.add(list.item(i));
      }
      System.out.format("%s %s %s%n", node.getPrefix(), node.getLocalName(),
          node.getNamespaceURI());
    }
  }

  public static void main(String[] args) throws Exception {
    String xml = "<a xmlns=\"http://domain/a\">"
        + "<pre:b xmlns:pre=\"http://domain/b\">" + "<c/>" + "<d xmlns=\"\">"
        + "<e/>" + "</d>" + "</pre:b>" + "</a>";

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse(
        new InputSource(new StringReader(xml)));
    print(doc.getDocumentElement());
  }
}
Run Code Online (Sandbox Code Playgroud)

此代码将打印:

null a http://domain/a
pre b http://domain/b
null c http://domain/a
null d null
null e null
Run Code Online (Sandbox Code Playgroud)