2011-09-12 16 views
1

SAX 또는 StAX를 사용하여 XHTML 파일을 읽는 것이 가장 효과적입니다. 하지만 엔티티가 해결되거나 대체 될 필요가 없습니다. 이상적으로 그들은 그대로 있어야합니다. DTD를 사용하고 싶지 않습니다. 다음 XHTML 파일을 감안할 때Java - XML을 읽고 모든 항목을 그대로 두십시오.

import javax.xml.stream._ 
import javax.xml.stream.events._ 
import java.io._ 

println("StAX Test - "+args(0)+"\n") 
val factory = XMLInputFactory.newInstance 
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false) 
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false) 

println("------") 
val xer = factory.createXMLEventReader(new FileReader(args(0))) 
val entities = new collection.mutable.ArrayBuffer[String] 
while (xer.hasNext) { 
    val event = xer.nextEvent 
    if (event.isCharacters) { 
     print(event.asCharacters.getData) 
    } else if (event.getEventType == XMLStreamConstants.ENTITY_REFERENCE) { 
     entities += event.asInstanceOf[EntityReference].getName 
    } 
} 
println("------") 
println("Entities: " + entities.mkString(", ")) 

...

<html> 
    <head> 
     <title>StAX Test</title> 
    </head> 
    <body> 
     <h1>Hallo StAX</h1> 
     <p id="html"> 
      &lt;div class=&quot;header&quot;&gt; 
     </p> 
     <p id="stuff"> 
      &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169; 
     </p> 
     Das war's! 
    </body> 
</html> 

... scala stax-test.scala stax-test.xhtml을 실행하는 발생합니다 :

여기

는 (사용 스칼라 2.8.x 실행) 예를입니다
StAX Test - stax-test.xhtml 

------ 


    StAX Test 


    Hallo StAX 

     <div class="header"> 


     berdies sollte das hier auch als Copyright sichtbar sein: ? 

    Das war's! 

------ 
Entities: Uuml 

그래서 모든 개체가 다소 성공적으로 대체되었습니다. 내가 기대와 내가 원하는 것은하지만,이입니다 것입니다 무엇 :

StAX Test - stax-test.xhtml 

------ 


    StAX Test 


    Hallo StAX 

     &lt;div class=&quot;header&quot;&gt; 


     &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169; 

    Das war's! 

------ 
Entities: // well, or no entities above and instead: 
// Entities: lt, quot, quot, gt, Uuml, #169 

이도 가능합니까? XHTML을 구문 분석하고 수정 한 다음 XHTML로 다시 출력하고 싶습니다. 그래서 엔티티가 결과에 남아 있기를 정말로 원합니다.

또한 나는 Uuml이 EntityReference 이벤트로보고되는 이유를 알지 못합니다.

답변

-2

자바에서는 정규식을 사용합니다.

public static void main(String... args) throws IOException { 
    BufferedReader buf = new BufferedReader(new FileReader(args[0])); 
    Pattern entity = Pattern.compile("&([^;]+);"); 
    Set<String> entities = new LinkedHashSet<String>(); 
    for (String line; (line = buf.readLine()) != null;) { 
    Matcher m = entity.matcher(line); 
    while (m.find()) 
     entities.add(m.group(1)); 
    } 
    buf.close(); 
    System.out.println("Entities: " + entities); 
} 

인쇄

Entities: [lt, quot, gt, Uuml, #169] 
+4

그리고 정규 표현식을 사용하여 XML을 구문 분석하려고하는 거의 모든 사람들처럼 잘못된 것입니다.예를 들어, 정규 표현식은 주석 및 CDATA 섹션에 나타나는 엔티티 유사 항목을 선택합니다. 주석에 세미콜론이없는 앰퍼샌드가 포함되어 있으면 혼란을 일으킬 수 있습니다. XML을 파싱하기 위해 정규 표현식을 사용하지 마십시오. 항상 틀리게 받아들입니다. 하향 투표. –

+0

@Michael Kay, 왜 그렇게 나쁜지에 대한 좋은 설명입니다. 나는 당신이 내가 가진 것보다 더 "야생"XML을 발견했다고 생각한다. 필자가 보았던 XML은 보통 목적을 위해 설계되었습니다. –

1

"나머지는 없지만 Uuml가의 EntityReference 이벤트로보고되는 이유"&Uuml;가 특정 반면, 나머지는 XML 스펙에 의해 정의된다는 것입니다에 대한 답변 HTML 4.0.

목표 수정 XHTML을 작성하는 것입니다 때문에, 는 HTML은 "인코딩"을 "US-ASCII"및/또는 "방법"을 "로 설정하여 숫자 엔티티 참조를 방출하는 시리얼 라이저를 강제로을 할 수 있습니다 ". XSLT spec (Java XML serializer의 기초가되는 것)은 메서드가 html 인 경우 serializer가 "문자 엔터티 참조를 사용하여 문자를 출력 할 수 있습니다"라고 말합니다. 인코딩을 ASCII로 설정하면 명명 된 엔티티가 지원되지 않는 경우 숫자 엔티티가 사용됩니다.

2

용어 설명 : &#x169;은 숫자 참조 (엔터티가 아님)이고 &#auml;은 엔터티 참조 (엔터티가 아님)입니다.

XML 구문 분석기가 응용 프로그램에 숫자 문자 참조를보고하지 않는다고 생각합니다. 항상 확장됩니다. 실제로, 애플리케이 션은 애트리뷰트 사이에 공백이 얼마나 많은지 신경 쓰지 않는다.

엔티티 참조의 경우 SAX와 같은 저수준 구문 분석 인터페이스는 엔티티 참조가 있는지 여부를보고합니다. 어떤 경우이든 요소 내용에는 나타나지만 속성 내용에는 나타나지 않습니다. ContentHandler가 아닌 LexicalHandler에만 통지되는 특수 이벤트가 있습니다.

관련 문제