我正在尝试解析一个简单的XML文件。看起来像这样
<?xml version="1.0" encoding="utf-8">
<resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_settings">Settings</string>
<string name="app_name">Colatris Sample</string>
<string name="cdata"><![CDATA[<p>Text<p>]]></string>
<string name="content_description_sample">Something</string>
<string name="countdown"><xliff:g example="5 days" id="time">%1$s</xliff:g> until holiday</string>
</resources>
这是我的解析方法:
List<CsString> extract(Document document) throws CsException {
List<CsString> csStrings = new ArrayList<>();
Element resources = document.getDocumentElement();
NodeList strings = resources.getElementsByTagName("string");
for (int i = 0; i < strings.getLength(); i++) {
Node string = strings.item(i);
csStrings.add(new CsString(string.getAttributes().getNamedItem("name").getNodeValue(), string.getTextContent()));
}
return csStrings;
}
我正在用这种方法构建传递的文档。
Document getDocument() throws CsException {
try {
Application application = core.getApplication();
AssetManager assetManager = application.getAssets();
InputStream inputStream = assetManager.open("colatris/values.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(inputStream);
} catch (IOException | ParserConfigurationException | SAXException e) {
throw new CsException("Unable to get parser");
}
}
一切都很好。除了cdata和countdown元素。我想获得字符串元素之间的文字。但是,解析器只返回CDATA内部的文本并剥离xliff标记。
String countdown = %1$s until holiday
String cdata = <p>Text<p>
我希望解析后的字符串看起来像这样,所以我可以按字面意思坚持它们。我需要能够在正确的位置使用元数据重建XML。
String countdown = <ns1:g example="5 days" id="time">%1$s</ns1:g> until holiday
String cdata = <![CDATA[<p>Text<p>]]>
Document是否有任何配置技巧,以便将两个元素之间的节点保持为文字字符串?对于大多数用户来说,使用CDATA是有意义的,但我需要解决这个问题。
答案 0 :(得分:1)
原因当然是您只是从string
元素中提取文本。您应该做的是获取子节点(或者可能是子节点,不知道文件的确切布局)并使用javax.xml.transform.Transformer
再次输出它们。代码看起来像:
NodeList list = document.getDocumentElement().getElementsByTagName("string");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty("omit-xml-declaration", "yes");
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
Node child = node.getFirstChild();
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(child), new StreamResult(writer));
System.out.println(writer.toString()); // Do your list thing in stead
}