11

簡単な情報を抽出するために必要な文字列入力があります。これが(mkyongからの)サンプルxmlです。

<?xml version="1.0"?>
<company>
    <staff>
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff>
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>

コード内でそれを解析する方法(String nameクラスにフィールドがあります):

public String getNameFromXml(String xml) {
        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            DefaultHandler handler = new DefaultHandler() {

                boolean firstName = false;

                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

                    if (qName.equalsIgnoreCase("firstname")) {
                        firstName = true;
                    }
                }

                public void characters(char ch[], int start, int length) throws SAXException {

                    if (firstName) {
                        name = new String(ch, start, length);
                        System.out.println("First name is : " + name);
                        firstName = false;
                    }

                }

            };

            saxParser.parse(xml.toString(), handler);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return name;
    }

を取得してjava.io.FileNotFoundExceptionいますが、ファイルを検索しようとしていることがわかりますmyprojectpath + the entireStringXML

私は何が間違っているのですか?

アドオン :

これが私の主な方法です:

public static void main(String[] args) {
        Text tst = new Text("<?xml version=\"1.0\"?><company>   <staff>     <firstname>yong</firstname>     <lastname>mook kim</lastname>       <nickname>mkyong</nickname>     <salary>100000</salary> </staff>    <staff>     <firstname>low</firstname>      <lastname>yin fong</lastname>       <nickname>fong fong</nickname>      <salary>200000</salary> </staff></company>");
        NameFilter cc = new NameFilter();
        String result = cc.getNameFromXml(tst);
        System.out.println(result);
    }
4

5 に答える 5

50

saxParser.parse(xml.toString(), handler);この行を次の行に置き換える必要があります。

saxParser.parse(new InputSource(new StringReader(xml)), handler);
于 2012-06-25T15:25:05.513 に答える
2

別の問題を強調します。ファイルを正しく読み取ると、この問題が発生する可能性があります。

方法

public void characters(char ch[], int start, int length) 

常に完全なテキスト要素が提供されるとは限りません。テキスト要素(コンテンツ)の「n」文字を一度に指定するのは自由です。ドキュメントから:

SAXパーサーは、連続するすべての文字データを1つのチャンクで返す場合もあれば、複数のチャンクに分割する場合もあります。

したがって、このメソッドの各呼び出しからテキスト要素文字列を作成し(たとえば、を使用して)、対応するメソッドが呼び出されたStringBuilder後にのみそのテキストを解釈/保存する必要があります。endElement()

これは今あなたに影響を与えないかもしれません。しかし、それは将来のある時点で発生するでしょう-おそらくあなたがそれを最も期待しないときに。小さなXMLドキュメントから大きなXMLドキュメントに移動するときに遭遇しました。ここでは、バッファリングによって小さなドキュメント全体を保持できましたが、大きなドキュメントは保持できませんでした。

例(擬似コード):

   public void startElement() {
      builder.clear();
   }
   public void characters(char ch[], int start, int length) {
      builder.append(new String(ch, start, length));
   }
   public void endElement() {
      // no do something with the collated text
      builder.toString();
   }
于 2012-06-25T15:39:05.780 に答える
1

マイベこの助け。これは、SAXよりも簡単なjavax.xml.parsers.DocumentBuilderを使用します

public Document getDomElement(String xml){
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
                is.setCharacterStream(new StringReader(xml));
                doc = db.parse(is); 

            } catch (ParserConfigurationException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            } catch (SAXException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            } catch (IOException e) {
                Log.e("Error: ", e.getMessage());
                return null;
            }
                // return DOM
            return doc;
    }

NodeListを使用してドキュメントをループし、各ノードをその名前で確認できます。

于 2012-06-25T15:21:40.037 に答える
0

ここからこの例をとったようです。文字列ではなく絶対パスを使用してファイルをメソッドに渡す必要がありますSAXParser.parse()。例をよく見てください。次のようにparse() 定義された方法

public void parse(File f,
                  DefaultHandler dh)
           throws SAXException,
                  IOException

とにかく文字列を解析したい場合。を取る別の方法がありますInputstream

public void parse(InputStream is,
                  DefaultHandler dh)
           throws SAXException,
                  IOException

次に、文字列をInputStreamに変換する必要があります。これがその方法です

于 2012-06-25T15:24:00.910 に答える
0

String最初のパラメーターとしてaを使用してparseを呼び出します。ドキュメントによると、その文字列はファイルに対してと解釈されURIます。

Stringを直接解析する場合は、メソッド(docuInputStreamで使用するために、最初にそれをに変換する必要があります。parse(InputSource is, DefaultHandler dh)

// transform from string to inputstream
ByteArrayInputStream in = new ByteArrayInputStream(xml.toString().getBytes());
InputSource is = new InputSource();
is.setByteStream(in);

// start parsing
saxParser.parse(xml.toString(), handler);
于 2012-06-25T15:26:11.877 に答える