Отбрасывать HTML-теги в пользовательских тегах при получении текста в XHTML с помощью SAX Parser в Groovy

Итак, я пытаюсь получить текст между тегами. До сих пор я был успешным. Но иногда, когда внутри моих пользовательских тегов есть специальные символы или теги html, я не могу получить текст. Образец xml выглядит так

<records>
      <car name='HSV Maloo' make='Holden' year='2006'>
        <ae_definedTermTitleBegin />Australia<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />1.02 <u>Accounting Terms</u>.<ae_clauseTitleEnd />
      </car>
      <car name='P50' make='Peel' year='1962'>
        <ae_definedTermTitleBegin />Isle of Man<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />Smallest Street-Legal Car at 99cm wide and 59 kg in weight<ae_clauseTitleEnd />
      </car>
      <car name='Royale' make='Bugatti' year='1931'>
        <ae_definedTermTitleBegin />France<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />Most Valuable Car at $15 million<ae_clauseTitleEnd />
      </car>
    </records>

Результат, который я получаю,

[Australia, Isle of Man, France]
[., Smallest Street-Legal Car at 99cm wide and 59 kg in weight, Most Valuable Car at $15 million]

Как видите, «Условия бухгалтерского учета» отсутствуют. Все, что я получаю, это точка. Как это исправить?

Код парсера саксофона

import javax.xml.parsers.SAXParserFactory
import org.xml.sax.helpers.DefaultHandler
import org.xml.sax.*

class SAXXMLParser extends DefaultHandler {
    def DefinedTermTitles = []
    def ClauseTitles = []
    def currentMessage
    def countryFlag = false

    void startElement(String ns, String localName, String qName, Attributes atts) {
        switch (qName) {
            case 'ae_clauseTitleBegin':
            //messages.add(currentMessage)
                countryFlag = true;
                break

            case 'ae_definedTermTitleBegin':
                //messages.add(currentMessage)
                countryFlag = true; 
                break           
         }      
    }   

    void characters(char[] chars, int offset, int length) {
        if (countryFlag) {
            currentMessage = new String(chars, offset, length)
            println(currentMessage)
        }
    }

    void endElement(String ns, String localName, String qName) {
        switch (qName) {        
            case 'ae_clauseTitleEnd':
                ClauseTitles.add(currentMessage)
                countryFlag = false;
                break
            case 'ae_definedTermTitleEnd':
                DefinedTermTitles.add(currentMessage)
                countryFlag = false; 
                break
         }
    }
}

person rkbom9    schedule 04.12.2014    source источник


Ответы (2)


Я не знаком с Groovy, поэтому вот решение на Java. Я считаю, что перевод прямолинейный.

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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

public class SaxHandler extends DefaultHandler {
    ArrayList<String> DefinedTermTitles = new ArrayList<>();
    ArrayList<String> ClauseTitles = new ArrayList<>();
    String currentMessage;
    boolean countryFlag = false;
    StringBuilder message = new StringBuilder();

    public void startElement(String ns, String localName, String qName, Attributes atts) {
        switch (qName) {
            case "ae_clauseTitleBegin":
                countryFlag = true;
                break;

            case "ae_definedTermTitleBegin":
                countryFlag = true; 
                break;           
         }      
    }   

    public void characters(char[] chars, int offset, int length) {
        if (countryFlag) {
            message.append(new String(chars, offset, length));
        }
    }

    public void endElement(String ns, String localName, String qName) {
        switch (qName) {        
            case "ae_clauseTitleEnd":
                ClauseTitles.add(message.toString());
                countryFlag = false;
                message.setLength(0);
                break;

            case "ae_definedTermTitleEnd":
                DefinedTermTitles.add(message.toString());
                countryFlag = false; 
                message.setLength(0);
                break;
         }
    }

    public static void main (String argv []) {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            String path = "INPUT_PATH_HERE";
            InputStream xmlInput = new FileInputStream(path + "test.xml");
            SAXParser saxParser = factory.newSAXParser();
            SaxHandler handler   = new SaxHandler();
            saxParser.parse(xmlInput, handler);

            System.out.println(handler.DefinedTermTitles);
            System.out.println(handler.ClauseTitles);

        } catch (Exception err) {
            err.printStackTrace ();
        }
    }
}

Вывод

[Australia, Isle of Man, France]
[1.02 Accounting Terms., Smallest Street-Legal Car at 99cm wide and 59 kg in weight, Most Valuable Car at $15 million]
person Alkis Kalogeris    schedule 04.12.2014

Поскольку вы задавали этот вопрос сейчас для разных библиотек, вот решение с XMLParser. Автор этого XML, возможно, не очень хорошо понимал, как работает XML. Если бы я был там, где вы, я бы предпочел установить некоторую фильтрацию, чтобы снова сделать это разумным (например, от <tagBegin/>X<tagEnd/> до <tag>x</tag>).

def xml = '''\
<records>
    <car name='HSV Maloo' make='Holden' year='2006'>
        <ae_definedTermTitleBegin />Australia<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />1.02 <u>Accounting Terms</u>.<ae_clauseTitleEnd />
    </car>
    <car name='P50' make='Peel' year='1962'>
        <ae_definedTermTitleBegin />Isle of Man<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />Smallest Street-Legal Car at 99cm wide and 59 kg in weight<ae_clauseTitleEnd />
    </car>
    <car name='Royale' make='Bugatti' year='1931'>
        <ae_definedTermTitleBegin />France<ae_definedTermTitleEnd />
        <ae_clauseTitleBegin />Most Valuable Car at $15 million<ae_clauseTitleEnd />
    </car>
</records>
'''

def underp = { l ->
    l.inject([texts: [:]]) { r, it ->
        if (it.respondsTo('name') && it.name().endsWith('Begin')) {
            r.texts[(r.last=it.name().replaceFirst(/Begin$/,''))] = ''
        } else if (it.respondsTo('name') && it.name().endsWith('End')) {
            r.last = null
        } else if (r.last) {
            r.texts[r.last] += (it instanceof String) ? it : it.text()
        }
        r
    }.texts
}

def root = new XmlParser().parseText(xml)
root.car.each{
    println underp(it.children()).inspect()
}

отпечатки

['ae_definedTermTitle':'Australia', 'ae_clauseTitle':'1.02 Accounting Terms.']
['ae_definedTermTitle':'Isle of Man', 'ae_clauseTitle':'Smallest Street-Legal Car at 99cm wide and 59 kg in weight']
['ae_definedTermTitle':'France', 'ae_clauseTitle':'Most Valuable Car at $15 million']
person cfrick    schedule 04.12.2014