我正在通过Java创建几个XML文件,到目前为止一切正常,但是现在我在尝试创建一个带有命名空间前缀节点的文件时遇到了问题,即像< tns:node>这样的东西. …< / tns:node>使用我的代码的重构版本,该代码已经用于没有名称空间的普通xml文件.
抛出的错误是:
org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: Ungültiges XML-Zeichen angegeben.
对不起那里的德语,它说“指定了无效的XML符号”.
发生错误的代码行:
Element mainRootElement = doc.createElement("tns:cmds xmlns:tns=\"http://abc.de/x/y/z\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://abc.de/x/y/z xyzschema.xsd\"");
为了消除错误导致转义相当长的字符串或这些行中的某些内容的可能性,我还尝试使用Element mainRootElement = doc.createElement(“tns:cmds”);但是,这会导致相同的错误.
这就是为什么我认为它与命名空间声明有关,即:用来做它,因为那是我能想到的唯一“无效”字符.
任何人都可以确认这是问题的根源吗?如果是这样,有一个简单的解决方案吗? Java DOM可以使用命名空间标签吗?
编辑:整个参考方法
private void generateScriptXML()
{
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
try
{
icBuilder = icFactory.newDocumentBuilder();
Document doc = icBuilder.newDocument();
Element mainRootElement = doc.createElement("tns:cmds xmlns:tns=\"http://abc.de/x/y/z\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://abc.de/x/y/z xyzschema.xsd\"");
doc.appendChild(mainRootElement);
mainRootElement.appendChild(getAttributes(doc,"xxx", "yyy", "zzz"));
mainRootElement.appendChild(getAttributes(doc,"aaa", "bbb", "ccc"));
mainRootElement.appendChild(getAttributes(doc,"ddd", "eee", "fff"));
...
...
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult streamResult = new StreamResult(new File(vfsPath));
transformer.transform(source, streamResult);
}
catch (Exception e)
{
e.printStackTrace();
}
}
解决方法:
错误的方法,尝试* NS变种:
Element mainRootElement = doc.createElementNS(
"http://abc.de/x/y/z", // namespace
"tns:cmds" // node name including prefix
);
第一个参数是命名空间,第二个参数是包含前缀/别名的节点名称.如果需要,将自动为命名空间添加命名空间定义.它也可以将它们设置为属性.
原始源中的命名空间是http://abc.de/x/y/z.使用属性xmlns:tns =“http://abc.de/x/y/z”,为命名空间定义别名/前缀tns. DOM api将隐式添加使用* NS方法创建的节点的名称空间.
xmlns和xml是特定名称空间的保留/默认名称空间前缀. xmlns的命名空间是http://www.w3.org/2000/xmlns/.
要使用setAttributeNS()添加xmlns:*属性,请使用xmlns命名空间:
mainRootElement.setAttributeNS(
"http://www.w3.org/2000/xmlns/", // namespace
"xmlns:xsi", // node name including prefix
"http://www.w3.org/2001/XMLSchema-instance" // value
);
但即使这样也不需要,就像元素一样,如果使用它添加属性节点,则会隐式添加命名空间定义.
mainRootElement.setAttributeNS(
"http://www.w3.org/2001/XMLSchema-instance", // namespace
"xsi:schemaLocation", // node name including prefix
"http://abc.de/x/y/z xyzschema.xsd" // value
);
命名空间前缀
如果您看到类似xsi:schemaLocation的节点名,则可以通过查找xmlns:xsi属性来解析.此属性是名称空间定义.该值是实际的命名空间.因此,如果您具有属性xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”,则可以将节点名称解析为{http://www.w3.org/2001/XMLSchema-instance }的schemaLocation.
如果要创建节点,则需要3个值:
>命名空间:http://www.w3.org/2001/XMLSchema-instance
>本地节点名称:schemaLocation
>前缀:xsi
前缀对于元素节点是可选的,但对于属性节点是必需的.以下三个XML将全部解析为元素节点名称{http://abc.de/x/y/z}:cmds:
>< tns:cmds xmlns:tns =“http://abc.de/x/y/z”/>
>< cmds xmlns =“http://abc.de/x/y/z”/>
>< other:cmds xmlns:other =“http://abc.de/x/y/z”/>
标签:java,dom,xml,namespaces
来源: https://codeday.me/bug/20190830/1765759.html