2011-09-12 8 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を実行することになります:

ここ

は(使用して、Scalaの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

Javaでは、正規表現を使用します。

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;が固有である一方、残りは、XMLの仕様によって定義されていることを、「残りはされていないながら、なぜUumlが実体参照イベントとして報告された」への答えHTML 4.0

は、修飾されたXHTMLを書くことを目標にしているため、は、エンコーディングを「US-ASCII」および/または「method」を「html " XSLT spec(Java XMLシリアライザの基礎をなす)では、メソッドがhtmlの場合、シリアライザは「文字エンティティ参照を使用して文字を出力する可能性があります。エンコーディングをASCIIに設定すると、名前付きエンティティがサポートされていない場合に数値エンティティを強制的に使用することがあります。

2

用語のビット:&#x169;は数値参照(エンティティではない)で、&#auml;はエンティティ参照(エンティティではありません)です。

XMLパーサーがアプリケーションに数値の文字参照を報告するとは思わない - それらは常に展開されます。本当に、あなたのアプリケーションは、属性間に空白がどれくらいあるかを気にする以上に、これ以上気にする必要はありません。

エンティティ参照の場合、SAXなどの低レベル解析インターフェイスは、エンティティ参照の存在を報告します。いずれにしても、要素コンテンツには発生したが属性コンテンツには発生していないことを報告します。 ContentHandlerではなくLexicalHandlerにのみ通知される特別なイベントがあります。

関連する問題