为什么可以通过在Java5中设置xmnls属性而在Java6中不设置来更改XML文档的名称空间?
我们有一个XSD来验证声明了名称空间的XML文档,但我们希望在没有名称空间的文档上使用它 在Java 5中,似乎可以对根元素的xmlns属性调用setAttribute,但在Java 6中失败,出现了一个例外: Exception in thread "main" org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Test'. 这是Java5或Java6中的bug还是两者都不是 要复制的代码:为什么可以通过在Java5中设置xmnls属性而在Java6中不设置来更改XML文档的名称空间?,java,xml,xsd,namespaces,Java,Xml,Xsd,Namespaces,我们有一个XSD来验证声明了名称空间的XML文档,但我们希望在没有名称空间的文档上使用它 在Java 5中,似乎可以对根元素的xmlns属性调用setAttribute,但在Java 6中失败,出现了一个例外: Exception in thread "main" org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Test'. 这是Java5或Java6中的bug还是两者都不是 要复
对我来说,这看起来不像一个bug,我很惊讶你能早点这么做。在已经构建DOM树之后在根元素上设置xmlns属性已经太晚了 此时,DOM树中的每个元素都已解析其前缀,并分配了本地名称和URI 如果您真的想通过操纵xmlns属性来实现这一点,那么在调用DOM解析器之前必须操纵输入流 或者,可以尝试遍历树并设置其中每个节点的名称空间URI
编辑:为了澄清,如果在某个地方有一个bug,那就是在Java5中——如果有人检查xmlns属性。正确的方法是获取根元素的URI。对我来说,这看起来不像是一个bug,我很惊讶您可以更早地这样做。在已经构建DOM树之后在根元素上设置xmlns属性已经太晚了 此时,DOM树中的每个元素都已解析其前缀,并分配了本地名称和URI 如果您真的想通过操纵xmlns属性来实现这一点,那么在调用DOM解析器之前必须操纵输入流 或者,可以尝试遍历树并设置其中每个节点的名称空间URI 编辑:为了澄清,如果在某个地方有一个bug,那就是在Java5中——如果有人检查xmlns属性。正确的方法是获取根元素的URI。IIRC,xmlns不是属性,而是名称空间声明。它可能看起来像xml文本中的一个属性,但它不是。它不应通过调用setAttribute进行设置。在我看来,Java5行为是一个BUG。IIRC,xmlns不是一个属性,它是一个名称空间声明。它可能看起来像xml文本中的一个属性,但它不是。它不应通过调用setAttribute进行设置。在我看来,Java5的行为是一个BUG
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));
}
}