2014-12-04 8 views
1

그래서 태그 사이에 텍스트를 가져 오려고합니다. 지금까지 나는 성공적이었다. 그러나 때로는 내 사용자 정의 태그 안에 특수 문자 또는 html 태그가있을 때 텍스트를 가져올 수 없습니다. 당신은 '회계 약관'없는 것을 알 수 있듯이Groovy의 SAX Parser를 사용하여 XHTML에서 텍스트를 가져 오는 동안 사용자 정의 태그 내의 html 태그를 무시하십시오.

<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] 

처럼 샘플 XML 보인다. 내가 얻는 것은 모두 점입니다. 이 문제를 어떻게 해결합니까?

그래서 여기에 Groovy를 잘 알고 아니에요 SAX 파서 코드

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 
     } 
    } 
} 

답변

0

자바의 솔루션입니다. 나는 그 번역이 아주 용감하다고 믿는다.

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] 
0

, 여기 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']