0

下面的代码没有正确地将输入数据转换为 XML。我这么认为是因为我不希望Transformer生成包含无效 xml 字符的输出(我说的是 &)。

这是代码:

package com.example.test.formatter;

import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
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;
import android.test.AndroidTestCase;
import android.util.Log;

public class XmlTest extends AndroidTestCase {

    public void testFormat() {

        try {
            String arbitraryInput = "Arbitrary input: \uD83D"; // we don't have control over this input

            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.newDocument();

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "true");

            StringWriter stringWriter = new StringWriter();
            StreamResult result = new StreamResult(stringWriter);
            DOMSource source = new DOMSource(document);

            Element root = document.createElement("root");
            Element subElement = document.createElement("key");
            subElement.setTextContent(arbitraryInput);
            root.appendChild(subElement);

            document.appendChild(root);

            stringWriter.getBuffer().setLength(0);
            transformer.transform(source, result);

            String parsed = stringWriter.toString(); // <root><key>Arbitrary input: &#55357;</key></root>
            Log.e("parsed", parsed);
        }
        catch(Throwable ex) {
            ex.printStackTrace();
        }

    }

}

我期待得到类似的东西

<root><key>Arbitrary input: &amp; #55357;</key></root>

但相反,我得到:

<root><key>Arbitrary input: &#55357;</key></root>

那么,如果我想得到 Transformer 的有效 XML 输出,我应该怎么做呢?

谢谢!

编辑:

我认为输出无效,因为当我尝试使用 PHP 处理生成的 XML 输出时,如下所示:

<?php

$data = "<root><key>Arbitrary input: &#55357;</key></root>";

$xmlDocument = new \DOMDocument();
$xmlDocument->loadXML($data);

我收到警告(如果环境配置为在警告时引发异常,则出现异常):

PHP Warning:  DOMDocument::loadXML(): xmlParseCharRef: invalid xmlChar value 55357 in Entity, line: 1 in /tmp/test.php on line 6
PHP Stack trace:
PHP   1. {main}() /tmp/test.php:0
PHP   2. DOMDocument->loadXML() /tmp/test.php:6

请注意,如果我尝试使用 DOMDocument (PHP) 处理以下代码,一切都会好起来的:

$data = " <root><key>Arbitrary input: &amp; #55357;</key></root>";

Java 转换器或 DOMDocument (PHP) 做错了什么。你能指出我吗?

谢谢!

4

1 回答 1

1

经过一番调查: \uD83D 确实是一个无效字符。\uD800 到 \uDFFF 的范围是 Unicode 标准为前导和尾随代理保留的,并且永远不会分配字符。

如果只有字符有效,Java 转换器使用的编码将是正确的。但既然不是这样,您就试图组装一个无效的 XML 文档。

构造

<root><key>Arbitrary input: &amp; #55357;</key></root>

显然没有反映输入数据,这意味着 key 的值是

Arbitrary input: & #55357;

这与您想要的不同。

于 2013-11-01T17:01:32.100 回答