Почему можно изменить пространство имен документа XML, установив атрибут xmnls в Java 5, но не в Java 6? - PullRequest
1 голос
/ 10 февраля 2010

У нас есть XSD, который проверяет XML-документ с объявленным пространством имен, но мы хотели бы использовать его в документе без такового.

В Java 5 похоже, что можно вызвать setAttribute() для атрибута xmlns корневого элемента, но в Java 6 происходит сбой за исключением:

Exception in thread "main" org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Test'.

Это ошибка в Java 5 или 6 или нет?

Код для воспроизведения:

import java.io.*;
import javax.xml.XMLConstants;
import javax.xml.parsers.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.validation.*;
import org.w3c.dom.Document;

public class NamespaceTest
{
    public static void main(String[] args) throws Exception
    {
        String namespace = "myNamespace";
        String xmlDoc = "<Test/>\n";
        String xsd = String.format(
                "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"%n" +
                "            targetNamespace=\"%1$s\" xmlns=\"%1$s\" elementFormDefault=\"qualified\">%n" +
                "     <xs:element name=\"Test\"/>%n" +
                "</xs:schema>%n", namespace);

        System.out.println("Original doc:\n" + xmlDoc);
        System.out.println("Original schema:\n" + xsd);

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document testXml = builder.parse(new ByteArrayInputStream(xmlDoc.getBytes("UTF-8")));
        testXml.getDocumentElement().setAttribute("xmlns", namespace);
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(xsd)));
        Validator validator = schema.newValidator();
        validator.validate(new DOMSource(testXml));

    }   
}

Ответы [ 2 ]

4 голосов
/ 10 февраля 2010

IIRC, xmlns не является атрибутом, это объявление пространства имен. Он может выглядеть как атрибут в тексте xml, но это не так. not должно быть установлено с помощью вызова setAttribute. ИМО, поведение Java 5 - BUG .

2 голосов
/ 10 февраля 2010

Это не похоже на ошибку для меня, и я удивлен, что вы могли сделать это раньше.Задать атрибут xmlns для корневого элемента после того, как дерево DOM уже построено, слишком поздно.

В этот момент каждому элементу в дереве DOM уже разрешен префикс, а также назначены локальное имя и URI..

Если вы действительно хотите сделать это, манипулируя атрибутом xmlns (который на самом деле не является надлежащим атрибутом), вы должны манипулировать потоком ввода перед вызовом синтаксического анализатора DOM.

В качестве альтернативы,может попытаться пройтись по дереву и установить URI пространства имен каждого узла в нем.

Изменить: , чтобы уточнить, если там где-то была ошибка, это было в Java 5 - есликто-то проверил атрибут xmlns.Правильный способ - получить URI корневого элемента.

...