簡體   English   中英

避免為空元素生成 XML 自閉合標簽並生成自定義<xml>開始標簽

[英]Avoid to generate XML self-closing tags for empty elements AND generate a custom <xml> start tag

我需要生成一個包含一些數據的 XML 文件以發送到我沒有動手的第 3 方系統(由另一家公司制造,我無法修改它或要求修改它)

這個其他系統不接受我生成的文檔,因為它有一些空元素的自閉合標簽: <tag/>而不是<tag></tag>

我目前的代碼看起來像那樣

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
StreamResult streamResult = new StreamResult(file);
transformer.transform(source, streamResult);

為了生成全結束標簽,我嘗試讓Transformer使用html輸出方法:

transformer.setOutputProperty(OutputKeys.METHOD, "html");

來源: http : //makble.com/the-self-closure-tag-problem-of-javaxxmltransform-package-dom-to-source

這適用於全封閉標簽,但我還有其他問題:

  • 未生成 XML 文檔起始標記(如<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
  • 特殊字符以 HTML 方式生成(如&eacute;而不是é

所以我發現我可以使用StAXResult而不是StreamResult這樣的:

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(new BufferedWriter(new FileWriter(nomFichier)));
        StAXResult streamResult = new StAXResult(writer);
        transformer.transform(source, streamResult);

這也適用於空元素上的完整結束標記,但我的 XML 文檔起始標記不完整:

<?xml version="1.0"?>

如果我嘗試使用 Transformer 的輸出屬性來定義它,這將不起作用:

        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
        transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
        transformer.setOutputProperty(OutputKeys.STANDALONE, "no");

由於使用了StAXResult所有屬性都將被忽略

Michael Kay ( https://stackoverflow.com/users/415448/michael-kay ) 在Processing xml file (Java) 中清楚地說明了這一點:

調用Transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); 除非變壓器產生序列化輸出,否則無效。 在您的情況下,變壓器不會產生序列化輸出,因為您將輸出發送到 StAXResult

我試圖配置XMLStreamWriter至少來定義編碼:

        XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(new BufferedWriter(new FileWriter(nomFichier)));
        writer.writeStartDocument("ISO-8859-1", "1.0");
        StAXResult streamResult = new StAXResult(writer);
        transformer.transform(source, streamResult);

這會導致添加“正確”的起始 XML 標記,但我也有來自 Transformer 的默認標記:

<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0"?>

最后我嘗試刪除 Transformer 默認標簽:

        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

但正如已經說過的,這不起作用,因為 Transformer 的輸出屬性被忽略了......

關於如何實現所有這些的任何想法?

  • 有效的 XML 起始標記( <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
  • 正確的字符編碼( é而不是&eacute;
  • 元素為空時的完整結束標記( <tag></tag>而不是<tag/>

我看到的唯一方法是使用XMLStreamWriterStAXResult編寫文檔,然后處理生成的文件以解析它並刪除<?xml version="1.0"?>元素並將其替換為硬編碼的<?xml version="1.0" encoding="ISO-8859-1"?>字符串,但我真的不想為此解析生成的 XML 文件,因為它可能非常大。

我正在尋找更優雅的解決方案!

在此先感謝您的幫助。

如果你想避免 XML 自閉標簽,你可以使用

@JsonProperty(value = "TEST")
@JsonSerializer(nullsUsing = NullSerializer.class)
private String test;

NullSerializer:它將是一個從 JsonSerializer 擴展的類,它將返回 null。

因此,如果“test”變量為空,則生成的 XML 消息將如下所示:

<TEST></TEST>

代替:

<TEST/>

如果要創建文件,為什么要使用 StAXResult? 正如您在回答中提到的,您正在將一種樹結構轉換為另一種樹結構。 XML 從不序列化,因此不考慮序列化設置。

您的主要問題似乎是您想避免自閉標簽,但這沒有意義,因為自閉標簽在語義上與一對開始/結束標簽相同。 我認為唯一的解決方法是使用 XSLT,通過添加一些不會在其間產生任何輸出的內容來誘使處理器編寫開始和結束標記。 但這大概也取決於您的處理器。 最后,您試圖將 XML 發送到無法理解 XML 的系統,因此您將始終不得不求助於黑客。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM