我打电话给API,我收到以下回复:
<Error>
<FormCd>940</FormCd>
<MetaData>
<Entry>
<Key>Balance Due</Key>
<Value>1500.99</Value>
</Entry>
</MetaData>
</Error>
<Error>
<FormCd>941</FormCd>
<MetaData>
<Entry>
<Key>Node</Key>
<Value>/Return/ReturnHeader/Filer/USAddress/ZIPCd</Value>
</Entry>
</MetaData>
</Error>
<Error>
<FormCd>942</FormCd>
<MetaData>
<Entry>
<Key>Description</Key>
<Value>Wages Amount</Value>
</Entry>
<Entry>
<Key>LineNumber</Key>
<Value>2</Value>
</Entry>
</MetaData>
</Error>
如何通过使用Xpath的常见元素在该文档中唯一标识/定位元素。我的意思是,当我尝试执行以下Xpath时:
/Error/FormCd
我收到错误,因为此Xpath有3个可能的值。由于这里有3个根元素,我不能这样做:
/Error/FormCd[0]
/Error/FormCd[1]
/Error/FormCd[2]
索引的Xpath不会起作用,因为我有超过1个根元素。
任何想法如何操纵给定的XML以便我可以轻松找到我想要的元素?也许为所有具有多个根元素的响应编写新的XML文档?把它全部置于1个根元素之下即错误?这可能太昂贵了。任何帮助或想法将不胜感激。谢谢。
修改
尝试使用以下实现添加根标记,将格式错误的XML转换为格式良好的XML:
try {
// String f = FileUtils.readFileToString(new File(file));
InputStream is = new FileInputStream(file);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document oldDoc = builder.parse(is);
Node oldRoot = oldDoc.getDocumentElement();
Document newDoc = builder.newDocument();
Element newRoot = newDoc.createElement("AllErrors");
newDoc.appendChild(newRoot);
newRoot.appendChild(newDoc.importNode(oldRoot, true));
ByteArrayOutputStream out = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(newDoc);
File fil = new File("newXml.xml");
StreamResult result = new StreamResult(fil);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
System.out.println(out);
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
我得到的错误是:
[Fatal Error] :21:3: The markup in the document following the root element must be well-formed.
org.xml.sax.SAXParseException; lineNumber: 21; columnNumber: 3; The markup in the document following the root element must be well-formed.
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)
at com.intuit.ctg.taxengine.automation.calc.ErrorXML.test(ErrorXML.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
答案 0 :(得分:1)
您可以将响应包含在名为&lt; root&gt;的新xml节点中。你的xpath也错了。
/Error/FormCd[0]
不可能,因为xpath索引从1开始。此外:
/Error/FormCd[2]
给你第二个&lt; FormCd&gt;来自所有&lt;错误&gt;的元素。据我所知,你只有一个&lt; FormCd&gt;在你的所有&lt;错误&gt;。你应该做的是:
/Error[1]/FormCd
从第一个&lt; Error&gt;
中为您提供所有&lt; FormCd&gt;(在本例中为一个)答案 1 :(得分:0)
将所有Error元素添加到List中,然后为其创建容器,可以生成格式错误的XML,格式正确。
List<InputStream> streams =
Arrays.asList(new ByteArrayInputStream("<AllErrors>".getBytes()), inputStream,
new ByteArrayInputStream("</AllErrors>".getBytes()) );
container = new SequenceInputStream(Collections.enumeration(streams));
wellFormedXML = IOUtils.toString(container);
从这里我可以使用java的XPATH库来执行XPath。