使用 SAX 解析器,需要所有 xml 元素(在特定元素下)作为字符串
Using SAX parser, need all the xml elements(under a particular element) as a string
我需要所有 xml 元素(在特定元素下)作为下面 xml 使用 sax 解析器的字符串。
样本xml:
<root>
<meta>
<elememtA>xx</elememtA>
</meta>
<payload>
<parent>
<child1>a</child1>
</parent>
<parent>
<child1>b</child1>
</parent>
</payload>
</root>
Sax 解析器实现:
public class UserHandler extends DefaultHandler {
@Override
public void startElement(String uri,
String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("payload")) {
//need all elements inside payload as string
}
例如,
我需要休闲输出:
<parent><child1>a</child1></parent><parent><child2>b</child2></parent>
您似乎需要 xml 形式的输出,即您需要 xml 形式的 parent
节点。 SAXParser 或 XPath 引擎使用节点和节点名称。您必须编写特殊代码 return 所需的输出 xml 这可能非常麻烦且难以维护。
轻松获得所需输出的一种方法 xml 是使用 XSLT。
考虑使用 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy-of select="//payload/parent"/>
</xsl:template>
</xsl:stylesheet>
将它放在一个名为 parentxslt.xml
的文件中,然后将您的输入 xml 放入 parent.xml
,然后您可以使用下面的 java 代码:
try
{
File stylesheet = new File( "parentxslt.xml" );
Transformer transformer = TransformerFactory.newInstance().newTransformer( new StreamSource(stylesheet) );
StreamSource xmlSource = new StreamSource( new File( "parent.xml" ) );
StringWriter sw = new StringWriter();
transformer.transform( xmlSource, new StreamResult( sw ) );
System.out.println( sw.toString().replaceAll("\\r\n\s*", "") );
}
catch ( Exception ex )
{
ex.printStackTrace();
}
这是工作代码。
你可以在输出的底部看到你的结果。享受吧。
输出
2017-06-14 09:43:49 DEBUG SaxTest:94 - start document
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : a
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : b
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent
2017-06-14 09:43:49 DEBUG SaxTest:41 - end document
2017-06-14 09:43:49 INFO SaxTest:148 - RESULT
<parent><child1>a</child1></parent><parent><child1>b</child1></parent>
Junit 中的代码 - 工作测试
package com.rizze.beans.labs.sof;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class SaxTest {
public static Logger logger = LoggerFactory.getLogger(SaxTest.class);
public class SaxProcess implements ContentHandler {
private boolean start= false;
private static final String START_ITEM = "payload";
private String result = "";
@Override
public void characters(char[] ch, int begin, int length) throws SAXException {
if(start == true){
logger.debug("STRING : "+new String(ch).substring(begin,begin+length));
result+=new String(new String(ch).substring(begin,begin+length));
}
}
@Override
public void endDocument() throws SAXException {
logger.debug("end document");
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){
start = false;
}
else{
if(start == true){
logger.debug("END - "+ localName + " - " + name);
result+="</"+name+">";
}
}
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
}
@Override
public void setDocumentLocator(Locator locator) {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
@Override
public void startDocument() throws SAXException {
start=false;
result = "";
logger.debug("start document");
}
@Override
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){
start = true;
}
else{
if(start == true){
//if already started ... go on
logger.debug("START - "+ localName + " - " + name);
result+="<"+name+">";
}
}
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
}
/**
* return resulting string
* @return
*/
public String getResult(){
return result;
}
}
@Test
public void test() {
String xml = "<root><meta><elememtA>xx</elememtA></meta><payload><parent><child1>a</child1></parent><parent><child1>b</child1></parent></payload></root>";
InputSource in = new InputSource(new StringReader(xml));
try {
XMLReader reader= SAXParserFactory.newInstance().newSAXParser().getXMLReader();
SaxProcess p=new SaxProcess();
reader.setContentHandler(p);
reader.parse(in);
logger.info("RESULT \n"+p.getResult());
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
我需要所有 xml 元素(在特定元素下)作为下面 xml 使用 sax 解析器的字符串。
样本xml:
<root>
<meta>
<elememtA>xx</elememtA>
</meta>
<payload>
<parent>
<child1>a</child1>
</parent>
<parent>
<child1>b</child1>
</parent>
</payload>
</root>
Sax 解析器实现:
public class UserHandler extends DefaultHandler {
@Override
public void startElement(String uri,
String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("payload")) {
//need all elements inside payload as string
}
例如,
我需要休闲输出:
<parent><child1>a</child1></parent><parent><child2>b</child2></parent>
您似乎需要 xml 形式的输出,即您需要 xml 形式的 parent
节点。 SAXParser 或 XPath 引擎使用节点和节点名称。您必须编写特殊代码 return 所需的输出 xml 这可能非常麻烦且难以维护。
轻松获得所需输出的一种方法 xml 是使用 XSLT。
考虑使用 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy-of select="//payload/parent"/>
</xsl:template>
</xsl:stylesheet>
将它放在一个名为 parentxslt.xml
的文件中,然后将您的输入 xml 放入 parent.xml
,然后您可以使用下面的 java 代码:
try
{
File stylesheet = new File( "parentxslt.xml" );
Transformer transformer = TransformerFactory.newInstance().newTransformer( new StreamSource(stylesheet) );
StreamSource xmlSource = new StreamSource( new File( "parent.xml" ) );
StringWriter sw = new StringWriter();
transformer.transform( xmlSource, new StreamResult( sw ) );
System.out.println( sw.toString().replaceAll("\\r\n\s*", "") );
}
catch ( Exception ex )
{
ex.printStackTrace();
}
这是工作代码。 你可以在输出的底部看到你的结果。享受吧。
输出
2017-06-14 09:43:49 DEBUG SaxTest:94 - start document
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : a
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : b
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent
2017-06-14 09:43:49 DEBUG SaxTest:41 - end document
2017-06-14 09:43:49 INFO SaxTest:148 - RESULT
<parent><child1>a</child1></parent><parent><child1>b</child1></parent>
Junit 中的代码 - 工作测试
package com.rizze.beans.labs.sof;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class SaxTest {
public static Logger logger = LoggerFactory.getLogger(SaxTest.class);
public class SaxProcess implements ContentHandler {
private boolean start= false;
private static final String START_ITEM = "payload";
private String result = "";
@Override
public void characters(char[] ch, int begin, int length) throws SAXException {
if(start == true){
logger.debug("STRING : "+new String(ch).substring(begin,begin+length));
result+=new String(new String(ch).substring(begin,begin+length));
}
}
@Override
public void endDocument() throws SAXException {
logger.debug("end document");
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){
start = false;
}
else{
if(start == true){
logger.debug("END - "+ localName + " - " + name);
result+="</"+name+">";
}
}
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
}
@Override
public void setDocumentLocator(Locator locator) {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
@Override
public void startDocument() throws SAXException {
start=false;
result = "";
logger.debug("start document");
}
@Override
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){
start = true;
}
else{
if(start == true){
//if already started ... go on
logger.debug("START - "+ localName + " - " + name);
result+="<"+name+">";
}
}
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
}
/**
* return resulting string
* @return
*/
public String getResult(){
return result;
}
}
@Test
public void test() {
String xml = "<root><meta><elememtA>xx</elememtA></meta><payload><parent><child1>a</child1></parent><parent><child1>b</child1></parent></payload></root>";
InputSource in = new InputSource(new StringReader(xml));
try {
XMLReader reader= SAXParserFactory.newInstance().newSAXParser().getXMLReader();
SaxProcess p=new SaxProcess();
reader.setContentHandler(p);
reader.parse(in);
logger.info("RESULT \n"+p.getResult());
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}