我正在通过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
属性来解决。此属性是namepace定义。该值是实际的名称空间。因此,如果您具有属性,xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
则可以将节点名称解析为{http://www.w3.org/2001/XMLSchema-instance}schemaLocation
(Clark表示法)。
如果要创建节点,则需要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"/>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句