2013-08-18 4 views
3

Groovy에서 XML을 파싱하면 케이크 조각이어야하지만 항상 문제가 발생합니다.네임 스페이스와 엔티티를 사용하여 Groovy에서 XML 구문 분석하기

나는이 같은 문자열을 구문 분석하고 싶습니다 : 나는 그것을 표준 방법 new XmlSlurper().parseText(body)을 수행 할 때

<html> 
<p> 
This&nbsp;is a <span>test</span> with <b>some</b> formattings.<br /> 
And this has a <ac:special>special</ac:special> formatting. 
</p> 
</html> 

은 파서는 &nbsp 실체에 대해 불평.

def parser = new org.ccil.cowan.tagsoup.Parser() 
def page = new XmlSlurper(parser).parseText(body) 

하지만 지금은 <ac:sepcial> 태그는 파서 immediatly 종료됩니다 - special 텍스트는 결과 DOM이 태그 내부되지 않습니다 : 이런 경우에 내 비밀 무기는 tagsoup 사용하는 것입니다. 나는 네임 스페이스 기능을 비활성화하는 경우에도 : 또 다른 방법은 표준 파서를 사용하고, 이와 같은 문서 타입을 추가했다

def parser = new org.ccil.cowan.tagsoup.Parser() 
parser.setFeature(parser.namespacesFeature,false) 
def page = new XmlSlurper(parser).parseText(body) 

: 이것은 내 파일의 대부분을 작동하는 것 같다

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

, 파서가 dtd를 가져 와서 처리하는 데는 시간이 걸립니다.

어떤 좋은 아이디어를 어떻게 해결할 수 있습니까?

PS : 당신은, 당신이 표준을 준수하기 위해 구문 분석할지 여부를 결정해야하는 DTD 경로를 가고, 또는 허용 파서 그냥 아무것도 받아 들일 것입니다

@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7') 
def processNode(node) { 
    def out = new StringBuilder("") 
    node.children.each { 
     if (it instanceof String) { 
      out << it 
     } else { 
      out << "<${it.name()}>${processNode(it)}</${it.name()}>" 
     } 
    } 
    return out.toString() 
} 

def body = """<html> 
<p> 
This&nbsp;is a <span>test</span> with <b>some</b> formattings.<br /> 
And this has a <ac:special>special</ac:special> formatting. 
</p> 
</html>""" 

def parser = new org.ccil.cowan.tagsoup.Parser() 
parser.setFeature(parser.namespacesFeature,false) 
def page = new XmlSlurper(parser).parseText(body) 
def out = new StringBuilder("") 
page.childNodes().each { 
    out << processNode(it) 
} 
println out.toString() 
"" 

답변

2

: 여기에 놀러 몇 가지 예제 코드 .

내 경험에 의하면 후자는 괜찮 았지만 문제가 거의 발생하지 않으므로 "특별"취급에 대한 귀하의 의견을 읽으면서 놀랐습니다. 빠른 테스트는 내가 그것을 재현 할 수 있다는 것을 보여 주었다 : 샘플에서이 명령

java net.sf.saxon.Query -x:org.ccil.cowan.tagsoup.Parser -s:- -qs:. !encoding=ASCII !indent=yes 

을 실행할 때,이 결과 모두 TagSoup 1.2과 1.2.1에서

<?xml version="1.0" encoding="ASCII"?> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml"> 
    <body> 
     <p> 
    This&#xa0;is a <span>test</span> with <b>some</b> formattings.<br clear="none"/> 
    And this has a <ac:special xmlns:ac="urn:x-prefix:ac">special</ac:special> formatting. 
    </p> 

    </body> 
</html> 

을 받았다. 그래서 예상대로 행동하는 나를 위해, "ac : special"태그 안에 나타나는 "special"텍스트.

DTD 변형의 경우 DTD를 해결하거나, 로컬 복사본을 참조하거나, DTD를 필요한 최소로 줄이기 위해 캐싱 프록시를 살펴볼 수 있습니다. &nbsp; 엔티티에서 다음을 수행하는 데 충분해야합니다.

<!DOCTYPE DOC[<!ENTITY nbsp "&#160;">]> 
+0

그것은 내가 사용했던 tagsoup 파서 (0.9.x)의 버전이었다 ... 1.2.1은 나에게 잘 작동한다. 고맙습니다! – rdmueller