XMLStreamWriter 写入包含冒号的标记

发布于 2025-01-16 17:10:26 字数 2791 浏览 0 评论 0原文

当我在标签名称中使用冒号(如下例所示)时,它最终会出错(没有冒号的标签没有问题)。

package test;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class SomeClass{

    public StringWriter test() throws XMLStreamException, TransformerConfigurationException, TransformerException {
        StringWriter stringOut = new StringWriter();
        XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(stringOut);
        xmlWriter.writeStartDocument("UTF-8", "1.0");
        xmlWriter.writeStartElement("SomeWordHere");
        {
            xmlWriter.writeStartElement("SomeName:enable");//<--- notice the colon
            xmlWriter.writeCharacters("true");
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndElement();
        xmlWriter.writeEndDocument();
        xmlWriter.flush();
        xmlWriter.close();

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

        StringWriter formattedStringWriter = new StringWriter();

        transformer.transform(new StreamSource(new StringReader(stringOut.toString())), new StreamResult(formattedStringWriter));

        return formattedStringWriter;
    }
}

如何编写仍然包含冒号并且不会出错的标签?

我正在尝试模拟 LEGO Stud.io 软件生成的 XML 输出 (Collada DAE),其中有如下部分包含带冒号的标签名称。

<library_materials>
    <material id="material_id_7" name="SOLID-BLUE">
        <instance_effect url="#effect_id_7-fx" />
        <extra>
            <technique profile="eyesight">
                <ScratchBump:enable> true </ScratchBump:enable>
                <MinScratchStrength:value> 0 </MinScratchStrength:value>
                <MaxScratchStrength:value> 0.2 </MaxScratchStrength:value>
                <BigScratch:enable> true </BigScratch:enable>
                <SmallScratch:enable> true </SmallScratch:enable>
            </technique>
        </extra>
    </material>
</library_materials>

When I use colon in the tag name like in the example below, it ends up in error (there is no problem with tags without the colon).

package test;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class SomeClass{

    public StringWriter test() throws XMLStreamException, TransformerConfigurationException, TransformerException {
        StringWriter stringOut = new StringWriter();
        XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(stringOut);
        xmlWriter.writeStartDocument("UTF-8", "1.0");
        xmlWriter.writeStartElement("SomeWordHere");
        {
            xmlWriter.writeStartElement("SomeName:enable");//<--- notice the colon
            xmlWriter.writeCharacters("true");
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndElement();
        xmlWriter.writeEndDocument();
        xmlWriter.flush();
        xmlWriter.close();

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

        StringWriter formattedStringWriter = new StringWriter();

        transformer.transform(new StreamSource(new StringReader(stringOut.toString())), new StreamResult(formattedStringWriter));

        return formattedStringWriter;
    }
}

How to write the tag that would still conain the colon and would not end up in error?

I am trying to emulate the XML output (Collada DAE) produced by LEGO Stud.io software, there are sections like the one below containing tag names with colons.

<library_materials>
    <material id="material_id_7" name="SOLID-BLUE">
        <instance_effect url="#effect_id_7-fx" />
        <extra>
            <technique profile="eyesight">
                <ScratchBump:enable> true </ScratchBump:enable>
                <MinScratchStrength:value> 0 </MinScratchStrength:value>
                <MaxScratchStrength:value> 0.2 </MaxScratchStrength:value>
                <BigScratch:enable> true </BigScratch:enable>
                <SmallScratch:enable> true </SmallScratch:enable>
            </technique>
        </extra>
    </material>
</library_materials>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

药祭#氼 2025-01-23 17:10:26

冒号用于命名空间,并且根据“XML 中的命名空间”规范,它不能在实体名称中使用。

规范指出:

[定义:如果文档符合命名空间规范,则该文档是命名空间格式良好的
本规范。 ]

在命名空间格式良好的文档中,可以得出以下结论:

  • 所有元素和属性名称均包含零个或一个冒号;
  • 实体名称、处理指令目标或符号名称均不包含任何冒号。

您可以使用一个技巧,将“SomeName”声明为命名空间,正如这个问题中所建议的: ​​xml 架构验证错误“前缀未绑定”

另一方面,“可扩展标记语言”规范指出:

注意:

XML 推荐中的命名空间 [XML 名称] 赋予以下含义:
包含冒号字符的名称。因此,作者不应使用
XML 名称中的冒号(除了命名空间用途外),但 XML
处理器必须接受冒号作为名称字符。

如果您更改解析器,您可以获得您想要的:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class CreateXmlFileDemo {

  public static void main(String[] args) {

    try {
      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
      Document doc = dBuilder.newDocument();
      Element rootElement = doc.createElement("SomeName:enable");

      doc.appendChild(rootElement);

      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();
      DOMSource source = new DOMSource(doc);

      StreamResult consoleResult = new StreamResult(System.out);
      transformer.transform(source, consoleResult);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

参考:https://www .w3.org/TR/REC-xml-names/

Colon is used for namespaces and per "Namespaces in XML" specification, it cannot be used in entity names.

The specification states:

[Definition: A document is namespace-well-formed if it conforms to
this specification. ]

It follows that in a namespace-well-formed document:

  • All element and attribute names contain either zero or one colon;
  • No entity names, processing instruction targets, or notation names contain any colons.

You can use a trick that is to declare "SomeName" as a namespace as it is suggested in this question: xml schema validation error "prefix is not bound".

On the other hand, "Extensible Markup Language" Specification state that:

Note:

The Namespaces in XML Recommendation [XML Names] assigns a meaning to
names containing colon characters. Therefore, authors should not use
the colon in XML names except for namespace purposes, but XML
processors must accept the colon as a name character.

If you change the parser you can get what you want:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class CreateXmlFileDemo {

  public static void main(String[] args) {

    try {
      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
      Document doc = dBuilder.newDocument();
      Element rootElement = doc.createElement("SomeName:enable");

      doc.appendChild(rootElement);

      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();
      DOMSource source = new DOMSource(doc);

      StreamResult consoleResult = new StreamResult(System.out);
      transformer.transform(source, consoleResult);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Reference: https://www.w3.org/TR/REC-xml-names/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文