Xercesを使ったJavaでのXML解析エラーの解決方法

このQ&Aのポイント
  • JavaのソースコードでXML文書を解析する際、XercesのDOMパーサを使用している際にエラーが発生しました
  • エラーの内容は「The entity name must immediately follow the '&' in the entity reference」というものでした
  • このエラーの解決策や、Javaのネットワークプログラミングに詳しい方に教えていただきたいです
回答を見る
  • ベストアンサー

Xercesを使ったjavaでのXML解析

DOMを使ってXML文書を解析するJavaのソースコードで、DOMパーサは、クラス org.apache.xerces.parsers.DOMParserで参照している下記のプログラムで、 [Fatal Error] :17:109: The entity name must immediately follow the '&' in the entity reference. org.xml.sax.SAXParseException; lineNumber: 17; columnNumber: 109; The entity name must immediately follow the '&' in the entity reference. のエラーが出てしまって、解決策が分かりかねています。Javaのネットワークプログラミングに詳しい方、御教示願えればと思います。 package nikkei; import java.io.ByteArrayInputStream; import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class TwitterSearch { public static void main(String[] args) throws Exception { TwitterSearch search = new TwitterSearch(); search.search("日経ソフトウエア"); } public void search(String keyword) throws Exception { SearchAPIClient client = new SearchAPIClient(); String xml = client.execute(keyword); parse(xml); } private void parse(String xml) throws Exception { DOMParser parser = new DOMParser(); try { parser.parse(new InputSource(new ByteArrayInputStream(xml.getBytes()))); Document doc = parser.getDocument(); NodeList entries = doc.getElementsByTagName("entry"); for (int i = 0; i < entries.getLength(); i++) { String name = null; String tweet = null; Element entry = (Element) entries.item(i); NodeList titleList = entry.getElementsByTagName("title"); if (titleList.getLength() == 1) { tweet = titleList.item(0).getTextContent(); } NodeList authorList = entry.getElementsByTagName("author"); if (authorList.getLength() == 1) { Element author = (Element) authorList.item(0); NodeList nameList = author.getElementsByTagName("name"); if (nameList.getLength() == 1) { name = nameList.item(0).getTextContent(); } } System.out.println(name + "さんのツイート"); System.out.println("\t" + tweet); } } catch (Exception e) { e.printStackTrace(); } } } package nikkei; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; public class SearchAPIClient { public String execute(String keyword) throws Exception { String url = "https://twitter.com/search?q=" + keyword; HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toString(entity); } else { return null; } } } よろしくお願いいたします。

  • Java
  • 回答数1
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • teketon
  • ベストアンサー率65% (141/215)
回答No.1

結論から言ってしまうと、Javascriptの入ったHTMLはDOMパーサーでは解析できません。 &、<、>が入っているため、ValidなXMLではないためです。 私だったら、下記のHTMLパーサを使用します。 http://jsoup.org/ -------以下サンプル package test; import java.net.URLEncoder; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class Test { public static void main(String[] args) throws Exception{ Document document = Jsoup.connect("https://twitter.com/search?q="+URLEncoder.encode("日経ソフトウェア","utf-8")).get(); System.out.println(document.getElementsByTag("title")); } }

tmiyoshi
質問者

お礼

jsoupで作成したDocumentから Elements classes = document.select("[class]"); for (Element identifier : classes) { if(identifier.className().equals("fullname js-action-profile-name show-popup-with-id")) { System.out.println(identifier.text() + "さんのツイート"); } if(identifier.className().equals("js-tweet-text tweet-text")) { System.out.println("\t" + identifier.text()); } } とすることで質問のプログラムでやりたいことはできるようになりました。 TwitterのSearch APIは今年の3月のV1.0 -> V1.1の仕様変更でかなり使い方が変わってしまったようです。以前は、<author>や<name>のタグを使ってDOMの構文解析をすればできていたようですが、V1.1からはJavaScriptを使うようになってしまったためか、その仕様が全然変わってしまったみたいです。 ありがとうございました。

関連するQ&A

  • JavaでのXMLパーサの使用について

    javaでパーサを使ってDOMツリーを作成したいのですが、パーサインスタンスが作成できずにエラーがでてしまいます。ちなみにコンパイルは通ります。 以下にソースとエラー内容を記述しますので、もしよろしかったらどなたか教えて下さい。 import java.io.*; import com.ibm.xml.parsers.*; import org.xml.sax.*; import org.w3c.dom.*; public static void main(String[] args){ try{      //XML文書作成 String xml = "<sample>Hello Java World</sample>"; //DOMパーサ作成 DOMParser parser = new DOMParser(); //入力ストリーム作成      StringReader sr = new StringReader(xml); InputSource is = new InputSource(sr); //パースする parser.parse(is); //ドキュメントを得る Document doc = parser.getDocument(); //トップレベル要素を得る Element el = doc.getDocumentElement(); System.out.println("Top Level Element: " + el.getTagName()); } catch(Exception e){ e.printStackTrace(); } } エラー内容: java.lang.NoClassDefFoundError: com.ibm.xml.parsers.DOMParser java.lang.Throwable(java.lang.String) java.lang.Error(java.lang.String) java.lang.LinkageError(java.lang.String) java.lang.NoClassDefFoundError(java.lang.String) void pkxml.dom.PsDomBean.makedom() void pkxml.dom.PsDomBean.makedom() void pkxmlsutabu.Sutabu.main(java.lang.String [])

  • XML MAGAZINE 03のサンプルについて教えてください

    XML MAGAZINE03のサンプルプログラム(最初のページから紹介している書籍検索プログラム)を作ろうとしています。そこで、BookFinder.javaでimportを使っていますが import org.w3c.dom.Document; import org.apache.xerces.parsers.DOMParser; import org.apache.xalan.xpath.xdom.XercesLiaison; import org.apache.xalan.xslt.XSLTProcessorFactory; import org.apache.xalan.xslt.XSLTResultTarget; importはパッケージのクラスを利用する と私は解釈していますが、では、PCにapacheを インストールしなくてはいけないのでしょうか? またw3cはどのように設定したらよいのでしょうか? ひょっとしたら根本的に勘違いや間違いをしているの かもしれませんが、どなたかご教授ください、お願いします。

    • 締切済み
    • XML
  • DOMでパースしているXML全体の出力方法

    お世話になります。 JavaでDOMを使ってXML操作をしたいと考えております。 おおよそ、以下のソースでparseできるところまで確認できました。 DOMParser parser = new DOMParser(); parser.parse("XMLファイルパス"); Document doc = parser.getDocument(); 開発中なので、DOM操作した結果のXMLを随時コンソールやログに 出力させたいのですが、たとえばdoc.toString()してもnullとなり、 正常に出力されません。 以下のようにElementを取得すると正常にアクセスできていることは 確認しています。 Element rootEl = doc.getDocumentElement(); System.out.println(rootEl.getNodeName()); なお、DOMライブラリにはxercesを用いております。 Dom4jのAPIも見てみましたが、それらしいメソッドを見つけることが できていません。 簡単にXMLを出力できることが理想です。 一般的な方法、よくやる手法など、みなさんよりご教示頂きたいです。

    • ベストアンサー
    • Java
  • ?__mode=rssのRSSデータからトラックバックをしたトラックバック先のURLを取得するプログラムの改正

    import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; public class GetTBlink { public static void main(String[] args) { try { String url = "http://app.blog.livedoor.jp/takapon_ceo/tb.cgi/50030092?__mode=rss"; DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document doc = builder.parse(url); Element root = doc.getDocumentElement(); NodeList list0 = root.getElementsByTagName("error"); Element element0 = (Element)list0.item(0); NodeList list1 = root.getElementsByTagName("rss"); Element element = (Element)list1.item(0); NodeList list2 = root.getElementsByTagName("channel"); Element element1 = (Element)list2.item(0); NodeList list3 = element1.getElementsByTagName("item"); for (int i=0; i < list3.getLength() ; i++) { Element element2 = (Element)list3.item(i); NodeList linkList = element2.getElementsByTagName("link"); Element linkElement = (Element)linkList.item(0); String link = linkElement.getFirstChild().getNodeValue(); System.out.println("リンク:" + link ); } } catch (Exception e) { e.printStackTrace(); } } } 以上のプログラムを次のように改正したいです。 pingurl = http://app.blog.livedoor.jp/takapon_ceo/tb.cgi/50030092として、 pingurlの後ろに ?__mode=rssを付加させるようにして String url を指定したい (String url = (pingurl)?__mode=rss のようなイメージ)  よろしくお願いします。

    • ベストアンサー
    • Java
  • XML文書をjavaを使ってCSV文書に...

    プログラム初心者なのですが csv.jpgのような形で、DOM,SAXどちらかを 使って変換したいのですが誰か教えてください。 xmlは -<item_list>- <item code="1"> <name>靴下</name> <maker>マイクロソフト</maker>- <option seq="1"> <attribute name="材質">ナイロン</attribute> <attribute name="サイズ">S</attribute> <attribute name="色">黒</attribute><attribute name="性別">男</attribute><price>500</price> </option>- <option seq="2"> <attribute name="材質">ナイロン</attribute> <attribute name="サイズ">M</attribute> <attribute name="色">黒</attribute> <attribute name="性別">男</attribute><price>500</price> ~ なものが続いてくる形です。 DTDは <?xml version="1.0" encoding="Shift_JIS" ?> <!ELEMENT item_list (item+)> <!ELEMENT item (name+,maker+,option+)> <!ATTLIST item code NMTOKENS #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT maker (#PCDATA)> <!ELEMENT option (attribute+,price)> <!ATTLIST attribute name CDATA #REQUIRED> <!ELEMENT price (#PCDATA)> でやっています。 現在のプログラムの状態は import java.io.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; import javax.xml.transform.dom.*; import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; //文書の入出力 class Exam3{ public static void main(String args[]) throws Exception{ SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); //SAXの準備 SampleHandler1 sh = new SampleHandler1(); //パンドアの作成 sp.parse(new FileInputStream("item_list_japan.xml"), sh); //XML文書をロード } } class SampleHandler1 extends DefaultHandler{ //パンドラクラス int YS=0; int YS2=0; int YS3=0; String[] ST= new String[80000000]; int ST1=0; int ab=0; int ab2=0; String tin="null"; StringBuffer sb = new StringBuffer(); //文字列を用意 public void endDocument(){ //文書の終了 try{ //文字列を書き出す PrintWriter pw = new PrintWriter (new BufferedWriter (new FileWriter("List2.csv"))); pw.println(sb); pw.close(); }catch(Exception e){} } public void startElement(String namespaceURI, String localName, String qName, //qNameは要素 Attributes attrs) { if(qName.equals("item")){ YS = 0; YS2=0; ab2=0; sb.append("商品コード"+","); for(int i=0;i<attrs.getLength();i++){ sb.append(attrs.getValue(i)+","); } }else if(qName.equals("name")){ sb.append("商品名"+","); }else if(qName.equals("maker")){ sb.append("製造元"+","); }else if(qName.equals("option")){ if(YS2==0){ sb.append("オプション"+","); YS2=1; YS3=0; } } if(qName.equals("attribute")){ if(YS3==0){ for(int i=0;i<attrs.getLength();i++){ if(attrs.getValue(i)!=""){ sb.append(attrs.getValue(i)+","); } } YS=1; } }else if(YS==1){ YS3=1; } tin=qName; } public void endElement(String namespaceURI,String localName,String qName){ if(qName.equals("option")){ sb.append("\r\n"); } //tin=qName; if(qName.equals("price")){ if(ab2==0){ sb.append("\r\n"); ab2=1; } sb.append(",,,,"); while(ST[ab]!=null){ sb.append(ST[ab]); ab++; } } } public void characters(char[] ch,int start,int length){ String str = new String(ch,start,length); if(tin=="attribute"){ ST[ST1]=(str+","); ST1++; } } } です。 回答よろしくお願いします。

    • 締切済み
    • XML
  • XMLパーサの種類について混乱してます

    XSLTをいじる必要に駆られて、現在Java1.4+JAXP1.1を利用しています。 いままで、javax.xml.transformをimportしてメソッドを実行するだけで、「変換系に何を使っているのか」については全く気にしていなかったのですが、その実体は何なのでしょうか? (XTとかXalanとか、単体の変換系がありますよね・・・?) また、DOMパーサ、SAXパーサもJAXPで使えますが、各々のパーサや変換系を集めてパッケージにしたものがJAXPなんでしょうか。 さらに、勉強中にXMLパーサという単語が出てきて混乱しています。XMLパーサは、DOM・SAX・XSLT等とは違うのでしょうか? (XMLパーサと名乗っているXercesは何に使うのでしょうか・・・) DTDとの関連も含めて解説して頂けたら嬉しいです。

    • ベストアンサー
    • Java
  • Eclispe上でXML書込み可能が、E以外出来ず

    Eclispe上では、任意の値を、例えば(ex.xml等)に書込み可能なのですが、 ランナブルjarにして、デスクトップ上に他ファイルも含めて置き、jarを起動して、 XMLに書込みしようとしても書込みできません。 XMLは標準で作成してます(windows7 Home edition 管理者権限で動作 JDK1.7.0_05)。 色々調査しましたが原因不明です。 読み込みは問題ありません。XSLTにも関連していないようです。 何が違うのでしょうか? みなさま、よろしくお願いいたします。 ソースは以下の通り、 import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; public class XMLBasic { /*-------------------------* * Variables. * *-------------------------*/ /*----- For XML -----*/ /* XSL */ final static String XSL_FILE="resource\\style.xsl"; /**/ static Element element; /*-------------------------* * Methods. * *-------------------------*/ /*----- Rewrite -----*/ public static void rw(String value, String tagName, int itemNum, String xmlFileName, String xslFileName) { Document document=null; try { document=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(xmlFileName)); } catch (SAXException e) { } catch (IOException e) { } catch (ParserConfigurationException e) {} document.getElementsByTagName(tagName).item(itemNum).getFirstChild().setNodeValue(value); TransformerFactory tfactory=TransformerFactory.newInstance(); Transformer transformer=null; try { transformer=tfactory.newTransformer(new StreamSource(new File(xslFileName))); } catch (TransformerConfigurationException e) {} try { transformer.transform(new DOMSource(document), new StreamResult(new File(xmlFileName))); } catch (TransformerException e) {} } }

    • ベストアンサー
    • Java
  • DOMParserを使いたいのですが

    こんにちは。 毎回初心者な質問で恐縮です。。 javaの中でXMLから特定のデータを抽出して表示したいのでインターネット上でサンプルがないか探していたところ、「アットマーク・アイティ」のホームページでちょうどよいものを見つけたのでそれを参考に作成しはじめたのですが、 DOMParser parser = new DOMParser(); という記述があり、ここでコンパイルがとまってしまいます。 import org.apache.xerces.parsers.*; がなかったのかと思い、記述を追加したところ今度は「パッケージは存在しません」と言われてしまいます。 jarファイルが足りないのかと調べていたのですが、このパッケージを使うために何が必要なのか参考資料がみつかりません。 「xerces」や「Parser」で調べたところ、自分のTOMCATのフォルダ内の\common\endorsedのフォルダ内に「xercesImpl.jar」「xmlParserAPIs.jar」がありました。 何がたりないのかご存知の方、教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • JavaによるXMLの読み込みについて

    現在、JavaでXMLを読みたく色々なサイト様を参考にさせて頂き プログラムを作成しております。 その結果、下記のようなプログラムで要素名を取得することは出来たのですが、 「属性名」と「属性の値」を読み込み表示することが中々上手くいきません。 どこに何を追加したらよいでしょうか。宜しければ教えて下さい。 -- sample.java -- sample.xml -------------------------------------- import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class sample { public static void main(String[] argv) { sample a = new sample(); a.runner(); } final static String file = "sample.xml"; public void runner() { DocumentBuilderFactory factory; DocumentBuilder builder; Node root; try { factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); factory.setValidating(true); root = builder.parse(file); showNodes(root, " "); } catch (ParserConfigurationException e0) { System.out.println(e0.getMessage()); } catch (SAXException e1){ System.out.println(e1.getMessage()); } catch (IOException e2) { System.out.println(e2.getMessage()); } } public void showNodes(Node node, String space) { NodeList nodes = node.getChildNodes(); for (int i=0; i<nodes.getLength(); i++) { Node node2 = nodes.item(i); if(!node2.getNodeName().equals("#text")){ System.out.println(space + "<" + node2.getNodeName() + ">"); showNodes(node2, space + " "); } } } }

    • ベストアンサー
    • Java
  • XML::XPathを使う

    エラーがでて期待する出力が出ず困っています。 ファイル名とXPathのコマンドライン引数をとり、 指定されたパスに一致するノードを出力するものです。 (参考書の写しなので、記述ミスはないと思います。) ■grabber.pl use XML::XPath; use XML::XPath::XMLParser; my $xpath = XML::XPath->new( filename => shift @ARGV ); my $nodeset = $xpath->find( shift @ARGV ); foreach my $node ( nodeset->get_nodelist ) { print XML::XPath::XMLParser::as_string( $node ) . "\n"; } コマンドラインに入力しているものは、 perl grabber.pl data.xml "/inventory/category/item/name" ■data.xml <?xml version="1.0"?> <inventory date="2001"> <category> <item id="2"> <name>aaaa</name> </item> </category> </inventory> です。 perl grabber.pl data.xml "/inventory/category/item/name" としても、下記にエラーが出ます。 Can't locate object method "get_nodelist" via package "nodeset" (perhaps you for got to load "nodeset"?) at grabber.pl line 5. いろいろ試してみたり調べたのですが、 行き詰ってしまいました。 期待する出力は"<name>aaaa</name>"なのですが・・・ どなたかこのエラーの原因がおわかりになるかた いらっしゃいますでしょうか。 環境は以下になります。 ・windowsxp ・activePerl モジュールのインストール済み ・XML-XPath ・XML-Parser 以上です。

    • ベストアンサー
    • Perl

専門家に質問してみよう