Java - XML NodeList.item() throws NullPointerException



当我解析Android XML布局时,Saxparser和阅读元素项目通过Nodelist,我得到NPE

NodeList list = e.getChildNodes(); // e is Element
for(int i = 0; i < list.getLength(); i++) {
    Node node = list.item(i);
    if(node == null) {
        continue;
    }
    if(node.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element) node;
        // process somehow it
    }
}

布局XML文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:gravity="center_horizontal" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@id/dbx_button_container" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true">
        <include android:layout_gravity="bottom" android:id="@id/dbx_button_bar" android:layout_height="fill_parent" layout="@layout/bottom_bar_light" />
    </FrameLayout>
    <LinearLayout android:orientation="vertical" android:id="@id/dbx_main_container" android:background="@color/lightBlueBackground" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/dbx_button_container">
        <TextView android:textSize="@dimen/dbx_action_bar_title_text_size" android:textColor="#ffffffff" android:gravity="center_vertical" android:id="@id/dbx_install_title" android:background="@color/actionBarBackground" android:paddingLeft="10.0dip" android:layout_width="fill_parent" android:layout_height="@dimen/dbx_action_bar_default_height" android:drawableLeft="@drawable/tab_dropbox" android:drawablePadding="3.0dip" />
        <View android:id="@id/dbx_separator" android:background="#ff000000" android:layout_width="fill_parent" android:layout_height="0.5dip" />
        <View android:id="@id/dbx_top_space" android:layout_width="fill_parent" android:layout_height="0.5dip" android:layout_weight="7.0" />
        <ImageView android:layout_gravity="center" android:id="@id/dbx_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_new" android:layout_weight="7.0" />
        <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">
            <TextView android:textStyle="bold" android:gravity="center" android:layout_gravity="center_horizontal" android:id="@id/dbx_install_main" android:paddingLeft="30.0dip" android:paddingRight="30.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="5.0dip" />
            <TextView android:textAppearance="?android:textAppearanceSmall" android:textSize="12.0sp" android:gravity="center" android:layout_gravity="center_horizontal" android:id="@id/dbx_install_sub" android:paddingLeft="30.0dip" android:paddingRight="30.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineSpacingMultiplier="1.25" />
        </LinearLayout>
        <View android:id="@id/dbx_bottom_space" android:layout_width="fill_parent" android:layout_height="0.5dip" android:layout_weight="10.0" />
    </LinearLayout>
</RelativeLayout>

我递归阅读所有内部元素,突然得到NPE:

at com.sun.org.apache.xerces.internal.dom.ParentNode.nodeListItem(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.ParentNode.item(Unknown Source)

那么为什么会发生?如何避免此例外并读取元素数据?

upd:有时npe被扔在getLength((中:

at com.sun.org.apache.xerces.internal.dom.ParentNode.nodeListGetLength(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.ParentNode.getLength(Unknown Source)

upd 2:整个身体

public List<DomElement> getChildNodes() {
    ArrayList<DomElement> elements = new ArrayList<DomElement>();
    NodeList list = e.getChildNodes();
    for(int i = 0; i < list.getLength(); i++) {
        Node node = list.item(i);
        if(node == null) {
            continue;
        }
        if(node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            elements.add(new DomElement(doc, element));
        }
    }
    return elements;
}

遇到以下链接。

https://www.davidpashley.com/2016/01/18/nullpointerexpections-in-xerces-j/

文章的摘要:

Xerces不是线程安全。通过儿童的结婚派加快表现并将其存储在节点的文档对象。在多线程应用程序中,这可以领导竞赛条件和无效互动感受。而且因为这是线程问题,问题是间歇性的,很难追踪。

解决方案是在DOM上同步您的代码,这意味着文档对象,无处可访问节点。我不确定确切需要保护哪种方法,但我相信它需要至少是任何会迭代节点符的功能。我会开始的通过保护所有访问和测试性能,并删除一些如果需要。

注意"同步(m_element.getownerdocument((({}"块围绕处理DOM的部分。NPE通常是扔在nl.getLength((或nl.item((调用上。

最新更新