2010-02-03 20 views
5

En el siguiente fragmento XML, ¿cuáles son los espacios de nombres de a, c, d y e? Se apreciará la referencia a la documentación o especificaciones.XML namespace defaulting/inheritance

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

Además, ¿qué frameworks de Java respetan el espacio de nombres oficial de forma predeterminada? Tengo tride org.w2c. * DOM paquetes, sin embargo, no parece resolver el URI de espacio de nombres correctamente? Por ejemplo, algo con funcionalidad similar a.

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

Respuesta

4

Según mi leal saber y entender, todas las API XML estándar en Java admiten espacios de nombres. Muchas de las API se escribieron antes de que se crearan espacios de nombres (o se volvieron populares, ya no recuerdo). A menudo es necesario 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()); 
    } 
} 

Este código imprimirá:

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

Un espacio de nombres declarados usando xmlns="..." se convierte en el valor predeterminado para todos los elementos dentro de ella (hasta que el defecto se vuelve a declarar luego en un elemento más profundo, por supuesto). Así que terminan con:

  • A utiliza http://domain/a (especificado como predeterminado)
  • b utiliza http://domain/b (especificada, pero no es un defecto)
  • C utiliza http://domain/a (heredado de a)
  • d no tiene espacio de nombres (especificado como una nueva configuración)
  • e no tiene espacio de nombres (heredado de d)

La especificación s relevante reflexión es el nombre XML de especificaciones, section 6.2:

El ámbito de un espacio de nombres predeterminado declaración se extiende desde el comienzo de la etiqueta de comienzo en el que aparece hasta el final de la etiqueta final correspondiente, excluyendo el alcance de cualquier declaración del espacio de nombres predeterminado interno . En el caso de una etiqueta vacía, el alcance es la etiqueta misma.

Una declaración de espacio de nombre predeterminada se aplica a todos los nombres de elementos 0prefixed dentro de su ámbito. Las declaraciones predeterminadas de espacio de nombres no se aplican directamente a nombres de atributos; la interpretación de los atributos no prefijados está determinada por el elemento en el que aparecen.

Si hay una declaración de espacio por defecto en su alcance, el ampliado nombre correspondiente a un nombre sin prefijo elemento tiene el URI del espacio de nombres por defecto como su nombre de espacio de nombres . Si no hay una declaración de espacio de nombres predeterminado en el alcance, el nombre del espacio de nombres no tiene ningún valor. El nombre de espacio de nombres para un nombre de atributo no prefijado siempre no tiene ningún valor. En todos los casos, el nombre local es la parte local (que es del curso igual que el nombre sin prefijo ).

11

Por lo que puedo decir sería de la siguiente manera.

  • una habrá http://domain/a ya que es el espacio de nombres predeterminado
  • b será http://domain/b ya que es el espacio de nombres definido para b
  • c será http://domain/a ya que es el espacio de nombres predeterminado
  • d será un espacio de nombres en blanco/no ajustado debido a la readaptación del espacio de nombres
  • e será un espacio de nombres en blanco/no ajustado, ya que está anidado dentro de la nueva declaración

Estoy basando esto fuera de este specification. A continuación hay un resumen para ayudar también.

Si hay una declaración de espacio por defecto en su alcance, el ampliado nombre correspondiente a un nombre sin prefijo elemento tiene el URI del espacio de nombres por defecto como su nombre de espacio de nombres . Si no hay una declaración de espacio de nombres predeterminado en el alcance, el nombre del espacio de nombres no tiene ningún valor. El nombre de espacio de nombres para un nombre de atributo no prefijado siempre no tiene ningún valor. En todos los casos, el nombre local es la parte local (que es del curso igual que el nombre sin prefijo ).