Jas*_*son 6 java xml stax extract
xml看起来像这样:
<statements>
<statement account="123">
...stuff...
</statement>
<statement account="456">
...stuff...
</statement>
</statements>
Run Code Online (Sandbox Code Playgroud)
我正在使用stax一次处理一个" <statement>",然后我就开始工作了.我需要将整个语句节点作为字符串获取,这样我就可以创建"123.xml"和"456.xml",甚至可以将其加载到由account索引的数据库表中.
使用这种方法:http://www.devx.com/Java/Article/30298/1954
我想做这样的事情:
String statementXml = staxXmlReader.getNodeByName("statement");
//load statementXml into database
Run Code Online (Sandbox Code Playgroud)
我有一个类似的任务,虽然最初的问题超过一年,但我找不到令人满意的答案.到目前为止最有趣的答案是Blaise Doughan的答案,但我无法让它在我期望的XML上运行(可能底层解析器的一些参数可能会改变它?).这里的XML非常简单:
<many-many-tags>
<description>
...
<p>Lorem ipsum...</p>
Devils inside...
...
</description>
</many-many-tags>
Run Code Online (Sandbox Code Playgroud)
我的解决方案
public static String readElementBody(XMLEventReader eventReader)
throws XMLStreamException {
StringWriter buf = new StringWriter(1024);
int depth = 0;
while (eventReader.hasNext()) {
// peek event
XMLEvent xmlEvent = eventReader.peek();
if (xmlEvent.isStartElement()) {
++depth;
}
else if (xmlEvent.isEndElement()) {
--depth;
// reached END_ELEMENT tag?
// break loop, leave event in stream
if (depth < 0)
break;
}
// consume event
xmlEvent = eventReader.nextEvent();
// print out event
xmlEvent.writeAsEncodedUnicode(buf);
}
return buf.getBuffer().toString();
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
XMLEventReader eventReader = ...;
while (eventReader.hasNext()) {
XMLEvent xmlEvent = eventReader.nextEvent();
if (xmlEvent.isStartElement()) {
StartElement elem = xmlEvent.asStartElement();
String name = elem.getName().getLocalPart();
if ("DESCRIPTION".equals(name)) {
String xmlFragment = readElementBody(eventReader);
// do something with it...
System.out.println("'" + fragment + "'");
}
}
else if (xmlEvent.isEndElement()) {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,提取的XML片段将包含完整的提取的正文内容,包括空格和注释.为了简洁起见,省略了按需过滤或使缓冲区大小可参数化的问题:
'
<description>
...
<p>Lorem ipsum...</p>
Devils inside...
...
</description>
'
Run Code Online (Sandbox Code Playgroud)
你可以使用StAX.您只需要将XMLStreamReader推进到start元素for语句.检查帐户属性以获取文件名.然后使用javax.xml.transform API将StAXSource转换为包装文件的StreamResult.这将推进XMLStreamReader,然后重复此过程.
import java.io.File;
import java.io.FileReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
xsr.nextTag(); // Advance to statements element
while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
File file = new File("out" + xsr.getAttributeValue(null, "account") + ".xml");
t.transform(new StAXSource(xsr), new StreamResult(file));
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不直接使用 xpath 呢?
您可以使用相当简单的 xpath 来获取所有“语句”节点。
就像这样:
//statement
Run Code Online (Sandbox Code Playgroud)
编辑#1:如果可能的话,看看dom4j。您可以相当简单地读取字符串并获取所有“语句”节点。
编辑#2:使用 dom4j,这就是你要做的:(来自他们的食谱)
String text = "your xml here";
Document document = DocumentHelper.parseText(text);
public void bar(Document document) {
List list = document.selectNodes( "//statement" );
// loop through node data
}
Run Code Online (Sandbox Code Playgroud)