6

私は次のxmlファイルを持っています:

<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="0" firstname="John"/>
</users>

次に、Javaで解析しようとしていますが、getchildnodesは間違った数の子ノードを報告します。

Javaコード:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(this.file);
document.getDocumentElement().normalize();
Element root = document.getDocumentElement();
NodeList nodes = root.getChildNodes();
System.out.println(nodes.getLength());

結果:3

また、ノード属性にアクセスするためのNPEを取得しているので、何かがひどく間違っていると推測しています。

4

4 に答える 4

4

子ノードは、空白の要素とテキストノードで構成されます。属性を処理する前に、ノードタイプを確認する必要があります。javax.xml.xpathまた、JavaSE5以降のJDK/JREで使用可能なAPIの使用を検討することもできます。

例1

この例は、DOMに対してXPathステートメントを発行する方法を示しています。

package forum11649396;

import java.io.StringReader;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?><users><user id='0' firstname='John'/></users>";

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse(new InputSource(new StringReader(xml)));

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        Element userElement = (Element) xpath.evaluate("/users/user", document, XPathConstants.NODE);
        System.out.println(userElement.getAttribute("id"));
        System.out.println(userElement.getAttribute("firstname"));
    }

}

例2

次の例は、に対してXPathステートメントを発行しInputSourceてDOMノードを取得する方法を示しています。これにより、XMLを自分でDOMに解析する必要がなくなります。

package forum11649396;

import java.io.StringReader;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?><users><user id='0' firstname='John'/></users>";

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        InputSource inputSource = new InputSource(new StringReader(xml));
        Element userElement = (Element) xpath.evaluate("/users/user", inputSource, XPathConstants.NODE);
        System.out.println(userElement.getAttribute("id"));
        System.out.println(userElement.getAttribute("firstname"));
    }

}
于 2012-07-25T12:18:54.640 に答える
3

3つの子ノードがあります。

  • 改行を含むテキストノード
  • 要素ノード(タグ付きユーザー)
  • 改行を含むテキストノード

したがって、子ノードを処理するときは、要素ノードを確認してください。

于 2012-07-25T12:19:44.980 に答える
1

テキストノードをカウントするノード間の「\n」を考慮に入れる必要があります。あなたはそれを使ってテストすることができますif(root.getNodeType() == Node.ELEMENT_NODE)

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(this.file);
        document.getDocumentElement().normalize();
        for(Node root = document.getFirstChild(); root != null; root = root.getNextSibling()) {
            if(root.getNodeType() == Node.ELEMENT_NODE) {
                NodeList nodes = root.getChildNodes();
                System.out.println(root.getNodeName() + " has "+nodes.getLength()+" children");
                for(int i=0; i<nodes.getLength(); i++) {
                    Node n = nodes.item(i);
                    System.out.println("\t"+n.getNodeName());
                }
            }
        }
于 2012-07-25T12:25:13.573 に答える
0

属性にアクセスしようとしたときに、NPEに関する最後のメモに対応する回答はありませんでした。

また、ノード属性にアクセスするためのNPEを取得しているので、何かがひどく間違っていると推測しています。

いくつかのサイトで次の提案を見たので、属性にアクセスする一般的な方法だと思います。

String myPropValue = node.getAttributes().getNamedItem("myProp").getNodeValue();

これは、ノードに常に属性が含まれている場合は正常に機能しますが、myProp属性がない場合はgetAttributesnullを返します。また、属性はあるが属性がない場合は、myPropnullgetNamedItemを返します。

私は現在使用しています

public static String getStrAttr(Node node, String key) {
    if (node.hasAttributes()) {
        Node item = node.getAttributes().getNamedItem(key);
        if (item != null) {
            return item.getNodeValue();
        }
    }

    return null;
}

public static int getIntAttr(Node node, String key) {
    if (node.hasAttributes()) {
        Node item = node.getAttributes().getNamedItem(key);
        if (item != null) {
            return Integer.parseInt(item.getNodeValue());
        }
    }

    return -1;
}

ユーティリティクラスではありますが、マイレージは異なる場合があります。

于 2013-01-12T04:50:10.563 に答える