当前位置: 首页 > 面试题库 >

在Java DOM中创建以名称空间为前缀的XML节点

谭繁
2023-03-14
问题内容

我正在通过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个值:

  1. 命名空间: http://www.w3.org/2001/XMLSchema-instance
  2. 本地节点名称: schemaLocation
  3. 前缀: 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"/>


 类似资料:
  • 面临使用JAXB解组的问题。我需要使用多个名称空间。Java类是为第三方提供的XSD生成的。因此,我不想在Java类中的XMLRootElement指定名称空间,也不想手动更改多个类。 编组逻辑如下: xmlelement类TokenRequest.java BasicInRequestType.java 我在package-info.java中指定了前缀 TokenRequest元素实际上引用了

  • 我正在开发一个客户端来使用 Web 服务,但由于某种原因,除非所有命名空间都正确且没有任何前缀,否则我的请求没有得到正确处理。 我所有的类都是由服务提供商使用提供的XSD和WSDL创建的。 NfeDadosMsg.class 包装信息.java TConsStatServ.class package br.inf.portalfiscal.nfe; 包装信息.java 输出xml: 由于某种原因,

  • 问题内容: 我正在寻找可以构造使用名称空间的XML文档的Java代码。我似乎无法使用我最喜欢的工具找到任何东西,因此希望有人可以帮助我。 问题答案: 我不确定您要做什么,但是我将jdom用于大多数xml问题,并且它支持名称空间(当然)。 代码: 产生以下xml: 其中应包含您需要的一切。希望能有所帮助。

  • 问题内容: 我有一个需要打开并进行一些更改的xml文件,其中之一是删除名称空间和前缀,然后保存到另一个文件。这是xml: 我可以进行所需的其他更改,但是找不到如何删除名称空间和前缀的方法。这是我需要的reusklt xml: 这是我的脚本,它将打开并解析xml并将其保存: 那么,如何在脚本中添加代码以删除名称空间和前缀呢? 问题答案: 按照Uku Loskit的建议替换标签。除此之外,请使用lxm

  • 问题内容: 我有下一个XML: 如何获得此节点?我试过了 但它返回一个空数组。我该怎么做? 问题答案: 您需要确保XML解析器支持名称空间。 您还应该确保关闭,最好使用try-with-resources。

  • 问题内容: 我有一个使用默认名称空间打印的文件。元素以ns2前缀打印,我需要将其删除,以及与我的代码的关系: 我希望它是: 这就是我的编码方式,据我所知,这足以使ns2消失: 生成的package-info结果如下: 我创建如下文件: generateClassesPackage是其中package-info.java及其元素所在的包。 Foo对象已定义,并具有以下元素: 我错过了吗?还是我误解了