在Java DOM中创建以名称空间为前缀的XML节点 [英] Creating namespace prefixed XML nodes in Java DOM

查看:135
本文介绍了在Java DOM中创建以名称空间为前缀的XML节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过Java创建多个XML文件,到目前为止一切正常,但是现在尝试创建带有命名空间前缀节点的文件时遇到了问题,例如,使用重构的<tns:node> ... </tns:node>之类的东西我的代码版本已经可以用于不带名称空间的普通xml文件.

I am creating several XML files via Java and up to this point everything worked fine, but now I've run into a problem when trying to create a file with namespace prefixed nodes, i.e, stuff like <tns:node> ... </tns:node> using a refactored version of my code that's already working for normal xml files without namespaces.

引发的错误是:

org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: Ungültiges XML-Zeichen angegeben. 

很抱歉德国人说指定了无效的XML符号".

Sorry for the German in there, it says "invalid XML-sign specified".

发生错误的代码行:

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");进行操作,但这会导致相同的错误.

To eliminate the possibility of the error resulting in escaping that rather long string or something among those lines I also tried just using Element mainRootElement = doc.createElement("tns:cmds");, however, this results in the same error.

这就是为什么我认为它与名称空间声明(即用于执行此操作的:)有关,因为这是我在该字符串中唯一想到的无效"字符.

That's why I figure it has something to do with the namespace declaration, i.e., the : used to do it, as that's the only "invalid" character I could think of in that string.

任何人都可以确认这是问题的根源吗?如果是这样,是否有一个简单的解决方案? Java DOM可以完全使用命名空间的标签吗?

Can anyone confirm this is the source of the problem? If so, is there an easy solution to it? Can Java DOM use namespaced tags at all?

整个方法供参考

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变体:

Wrong method, try the *NS variants:

Element mainRootElement = doc.createElementNS(
   "http://abc.de/x/y/z", // namespace
   "tns:cmds" // node name including prefix
);

第一个参数是名称空间,第二个参数是节点名称,包括前缀/别名.如果需要,将自动为名称空间添加名称空间定义.它也可以将它们设置为属性.

First argument is the namespace, second the node name including the prefix/alias. Namespace definitions will be added automatically for the namespace if needed. It works to set them as attributes, too.

原始源中的名称空间是http://abc.de/x/y/z.通过属性xmlns:tns="http://abc.de/x/y/z",为命名空间定义了别名/前缀tns. DOM api将为使用* NS方法创建的节点隐式添加名称空间.

The namespace in your original source is http://abc.de/x/y/z. With the attribute xmlns:tns="http://abc.de/x/y/z" the alias/prefix tns is defined for the namespace. The DOM api will implicitly add namespaces for nodes created with the *NS methods.

xmlnsxml是特定名称空间的保留/默认名称空间前缀. xmlns(命名空间定义)的名称空间是http://www.w3.org/2000/xmlns/.

xmlns and xml are reserved/default namespace prefixes for specific namespaces. The namespace for xmlns (namespace definitions) is http://www.w3.org/2000/xmlns/.

要使用setAttributeNS()添加xmlns:*属性,请使用xmlns命名空间:

To add an xmlns:* attribute with setAttributeNS() use the xmlns namespace:

mainRootElement.setAttributeNS(
  "http://www.w3.org/2000/xmlns/", // namespace
  "xmlns:xsi", // node name including prefix
  "http://www.w3.org/2001/XMLSchema-instance" // value
);

但是即使那样也不需要.就像对于元素一样,如果使用名称空间定义添加属性节点,则将隐式添加名称空间定义.

But even that is not needed. Just like for elements, the namespace definition will be added implicitly if you add an attribute node using it.

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表示法).

Namespaces Prefixes

If you see a nodename like xsi:schemaLocation you can resolve by looking for the xmlns:xsi attribute. This attribute is the namepace definition. The value is the actual namespace. So if you have an attribute xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" the node name can be resolved to {http://www.w3.org/2001/XMLSchema-instance}schemaLocation (Clark notation).

如果要创建节点,则需要3个值:

If you want to create the node you need 3 values:

  1. 名称空间:http://www.w3.org/2001/XMLSchema-instance
  2. 本地节点名称:schemaLocation
  3. 前缀:xsi
  1. the namespace: http://www.w3.org/2001/XMLSchema-instance
  2. the local node name: schemaLocation
  3. the prefix: xsi

对于元素节点,前缀是可选的,对于属性节点,前缀是必需的.以下三种XML都将其解析为元素节点名称{http://abc.de/x/y/z}cmds:

The prefix is optional for element nodes, but mandatory for attribute nodes. The following three XMLs resolve all to the element node name {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"/>
  • <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节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆