Пропуск узлов с саксофоном - PullRequest
4 голосов
/ 29 июля 2010

Можно ли пропускать узлы при разборе и как это skippedEntity как-то связано с этим?

Рассмотрим этот XML:

<?xml version="1.0"?>

<nutrition>

<daily-values>
    <total-fat units="g">65</total-fat>
    <saturated-fat units="g">20</saturated-fat>
    <cholesterol units="mg">300</cholesterol>
    <sodium units="mg">2400</sodium>
    <carb units="g">300</carb>
    <fiber units="g">25</fiber>
    <protein units="g">50</protein>
</daily-values>

</nutrition>

Я хочу пропустить "натрий "элемент

Ответы [ 3 ]

7 голосов
/ 30 июля 2010

Вы можете сделать что-то вроде следующего:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();
        xr.setContentHandler(new MyContentHandler(xr));
        xr.parse("input.xml");
    }
}

MyContentHandler

Этот класс отвечает за обработку вашего XML-документа. Когда вы нажимаете на узел, который хотите игнорировать, вы можете поменять его в IgnoringContentHandler, который проглотит все события для этого узла.

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class MyContentHandler extends DefaultHandler {

    private XMLReader xmlReader;

    public MyContentHandler(XMLReader xmlReader) {
        this.xmlReader = xmlReader;
    }

    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        if ("sodium".equals(qName)) {
            xmlReader.setContentHandler(new IgnoringContentHandler(xmlReader,
                    this));
        } else {
            System.out.println("START " + qName);
        }
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("END " + qName);
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        System.out.println(new String(ch, start, length));
    }

}

IgnoringContentHandler

Когда IgnoringContentHandler завершает глотание событий, он передает управление вашему основному ContentHandler.

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class IgnoringContentHandler extends DefaultHandler {

    private int depth = 1;
    private XMLReader xmlReader;
    private ContentHandler contentHandler;

    public IgnoringContentHandler(XMLReader xmlReader, ContentHandler contentHandler) {
        this.contentHandler = contentHandler;
        this.xmlReader = xmlReader;
    }

    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        depth++;
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        depth--;
        if(0 == depth) {
           xmlReader.setContentHandler(contentHandler);
        }
    }

}
3 голосов
/ 29 июля 2010

Пожалуйста, отредактируйте ваше сообщение, включив в него образец XML и описание того, что вы подразумеваете под "пропускать узлы".

Поскольку ваш синтаксический анализатор получает контроль над каждым событием, вы можете выбрать ничего не делать, основываясь на любых критериях, которые вы пожелаете. Если вы хотите пропустить целое поддерево, вы должны установить глобальный флаг при обнаружении начального элемента поддерева и очистить флаг в конечном элементе; затем используйте флаг для управления обработкой содержащихся узлов.

1 голос
/ 04 декабря 2011

К сожалению, у меня нет привилегий комментировать другие ответы. Я просто хотел исправить неверное утверждение Уэйна о том, что ответ Блейза «не работает». Я попробовал этот код, и он действительно выводит все значения из данных примера, за исключением значения для Sodium - что, я думаю, именно то, что искал ОП.

...