2010-02-03 21 views
5

Nel seguente snippet XML quali sono gli spazi dei nomi di a, c, d ed e? Si farebbe riferimento alla documentazione o alle specifiche.XML namespace defaulting/inheritance

<a xmlns="http://domain/a"> 
    <pre:b xmlns:pre="http://domain/b"> 
     <c/> 
     <d xmlns=""> 
      <e/> 
     </d> 
    </pre:b> 
</a> 

Inoltre, quali framework Java rispettano il default del namespace ufficiale? Ho tride org.w2c. * Pacchetti DOM, tuttavia non sembra che risolva correttamente l'URI dello spazio dei nomi? Ad esempio, qualcosa con funzionalità simili a.

String namespace = DocumentParser.parse(). 
        getElement("a"). 
        getElement("b"). 
        getElement("c"). 
        getNamespaceURI(); 

risposta

4

Per quanto ne so, tutte le API XML standard in Java supportano gli spazi dei nomi. Molte API sono state scritte prima che i namespace venissero creati (o diventati popolari - non ricordo più). Spesso è necessario enable support:

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()); 
    } 
} 

Questo codice stamperà:

null a http://domain/a 
pre b http://domain/b 
null c http://domain/a 
null d null 
null e null 
8

Un namespace dichiarato utilizzando xmlns="..." diventa il predefinito per tutti gli elementi in esso (finché il difetto è poi ridichiarato in un elemento profondo, ovviamente). Così si finisce con:

  • A utilizza http://domain/a (specificato come impostazione predefinita)
  • b utilizza http://domain/b (specificato, ma non è un difetto)
  • C utilizza http://domain/a (ereditato da a)
  • d non ha namespace (specificato come una nuova impostazione predefinita)
  • e non ha spazio dei nomi (ereditato da d)

Il relativo spec s essione è il nomi XML spec, section 6.2:

L'ambito di un namespace predefinito dichiarazione si estende dall'inizio dello start-tag in cui appare alla fine del corrispondente end-tag, ad esclusione l'ambito di tutte le dichiarazioni interne dello spazio dei nomi di default di . Nel caso di un tag vuoto, lo scope è il tag stesso.

Una dichiarazione dello spazio dei nomi predefinita si applica a tutti i nomielemento non prefisso nell'ambito. Le dichiarazioni di default dello spazio dei nomi non si applicano direttamente ai nomi degli attributi; l'interpretazione di degli attributi non prefissati è determinata dall'elemento in cui vengono visualizzati.

Se c'è una dichiarazione di default namespace portata, il espanso nome corrispondente ad un nome elemento unprefixed ha l'URI del namespace predefinito come nome namespace . Se non è presente una dichiarazione di spazio dei nomi predefinita nell'ambito, il nome dello spazio dei nomi non ha valore. Il nome dello spazio dei nomi per un attributo non prefisso nome non ha sempre alcun valore. In tutti i casi, il nome locale è locale (che è di tipo uguale al nome prefisso stesso).

11

Da quello che posso dire sarebbe il seguente.

  • una sarà http://domain/a come cioè lo spazio predefinito
  • b sarà http://domain/b come quello è il namespace definito per b
  • c sarà http://domain/a come cioè lo spazio predefinito
  • d sarà uno spazio dei nomi vuoto/non impostato a causa della reimpostazione del namespace
  • e sarà uno spazio dei nomi vuoto/non impostato, poiché è annidato all'interno della nuova dichiarazione

Sto basando questo su questo specification. Di seguito è riportato un preventivo per aiutare.

Se c'è una dichiarazione di default namespace portata, il espanso nome corrispondente ad un nome elemento unprefixed ha l'URI del namespace predefinito come nome namespace . Se non è presente una dichiarazione di spazio dei nomi predefinita nell'ambito, il nome dello spazio dei nomi non ha valore. Il nome dello spazio dei nomi per un attributo non prefisso nome non ha sempre alcun valore. In tutti i casi, il nome locale è locale (che è di tipo uguale al nome prefisso stesso).