【已解决】Android中用DOM方式解析xml时使用getElementsByTagName去获得节点结果为空

【问题】

折腾:

【未解决】Android中解析/res/raw文件夹下面的xml文件

时,试了试下面代码:

public static ArrayList<XmlItem> getXmlItems(InputStream inputStream, String tag){
    ArrayList<XmlItem> xmlItemList = new ArrayList<XmlItem>();
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder builder;
    try {
      builder = factory.newDocumentBuilder();
          Document document = builder.parse(inputStream);
          Element root = document.getDocumentElement();

          NodeList nodeList = root.getElementsByTagName(tag);
          //NodeList nodeList = root.getElementsByTagNameNS(namespaceURI, localName)(tag);
          for(int idx = 0; idx < nodeList.getLength(); idx++){
          	Node curNode = nodeList.item(idx);
          	String nodeName = curNode.getNodeName(); 
          }
    } catch (ParserConfigurationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (SAXException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    return xmlItemList;
  }
    
  //public String getUniversalDataGroup() {
  public UIDataGroup getUniversalDataGroup() {
    UIDataGroup uiDataGroup = new UIDataGroup();
    
    //parse xml file to UIDataGroup

    String menuTag = "Menu";
    //String tabMenuTag = "TabMenu";
        //ArrayList<XmlItem> rootMenuItemList= XmlHelper.getXmlItems(groupMenuFilename, menuTag,null);
        //XmlItem rootMenuItem = 

        InputStream inputStream = AppContext.getInstance().getResources().openRawResource(R.raw.groupmenu);
        //ArrayList<XmlItem> rootMenuItemList= XmlHelper.getXmlItems(inputStream, menuTag,null);
        ArrayList<XmlItem> rootMenuItemList= XmlHelper.getXmlItems(inputStream, menuTag);

    return uiDataGroup;
  }

结果用getElementsByTagName去获得对应的xml:

<?xml version="1.0" encoding="UTF-8"?>
<Menu>
  <TabMenu Label="HART">
    ......
  </TabMenu>
  <TabMenu Label="Device">
    ......
  </TabMenu>
  ......
</Menu>

竟然得到是空的NodeList:

getElementsByTagName return empty node list

【解决过程】

1.使用自动提示,看了看,root还有另外一个函数:

public abstractAttrgetAttributeNodeNS (StringnamespaceURI,StringlocalName)

Added inAPI level 1

Retrieves an Attr node by local name and namespace URI.

Per [ XML Namespaces ] , applications must use the value null as thenamespaceURI parameter for methods if they wish to have no namespace.

Parameters

namespaceURI 

localName 

Returns
  • The Attr node with the specified attribute local name and namespace URI ornull if there is no such attribute.
Throws

DOMException

NOT_SUPPORTED_ERR: May be raised if the implementation does not support the feature "XML" and the language exposed through the Document does not support XML Namespaces (such as [ HTML 4.01 ]).

但是不知道:

是不是由于namespace的原因

以及如何获得当前的namespace(好像当然xml中没有什么namespace)

2.参考:

xml – GetElementsByTagName returns empty list – Stack Overflow

xml – android getElementsByTagName returns empty list – Stack Overflow

没看到解决办法。

3.后来看到:

Element | Android Developers

的提示,貌似是可以通过:

root的另外一个函数:

getNamespaceURI()

去获得当然namespace,然后再去试试:

//NodeList nodeList = root.getElementsByTagName(tag);
          String namespaceURI = root.getNamespaceURI();
          NodeList nodeList = root.getElementsByTagNameNS(namespaceURI, tag);

看看结果如何,调试发现得到的namespace也是null。

所以还是无法获得对应的我要的内容。

4.后来看到:

android getElementsByTagName returns empty list (1 answer)

还是没解决办法。

5.参考:

Element.getElementsByTagName – Web API Interfaces | MDN

去看看document是否有“ getElementById ”,不过待会再试。

6.不过试了试,去查找,非root节点,找其他的tag:

//NodeList nodeList = root.getElementsByTagName(tag);
          NodeList nodeList = root.getElementsByTagName("TabMenu");

就可以找到了:

search another tabmenu tag can found 4 node list

7.突然想到了,是不是:

当然已经是处于root节点了,所以无法获得对应的root节点的tag?

但是可以(通过tag去)获得root节点其下的其他的节点?

所以,去验证一下此想法:

builder = factory.newDocumentBuilder();
          Document document = builder.parse(inputStream);
          Element root = document.getDocumentElement();
          
          Element menuElement = document.getElementById("Menu");
          NodeList tabNodeList = menuElement.getElementsByTagName("TabMenu");

结果还是获得空值:

getElementById for Menu also empty

8.再去试试:

NodeList nodeList = root.getChildNodes();

看看结果,是可以获得对应的子节点的:

[org.apache.harmony.xml.dom.TextImpl@211914f8, org.apache.harmony.xml.dom.ElementImpl@21191668, org.apache.harmony.xml.dom.TextImpl@21194f58, org.apache.harmony.xml.dom.ElementImpl@21194fb8, org.apache.harmony.xml.dom.TextImpl@21198c80, org.apache.harmony.xml.dom.ElementImpl@21198d48, org.apache.harmony.xml.dom.TextImpl@2119f038, org.apache.harmony.xml.dom.ElementImpl@2119f100, org.apache.harmony.xml.dom.TextImpl@211a16c0]

其中的4个ElementImpl才是我们所关心的节点。

9.也注意到:

xml – android getElementsByTagName returns empty list – Stack Overflow

中提到了,其遇到此问题的android的版本是3.0或3.1

所以去看看我此处的:

Samsung Galaxy Tab 3 GT-P5210

android版本是:4.2.2

结果也出现此问题。。。

【总结】

算了,截至目前:

虽然会遇到上述bug:

即:

NodeList nodeList = root.getElementsByTagName("Menu");

获得空列表。

但是此处,还是可以通过,直接使用

NodeList nodeList = root.getElementsByTagName("TabMenu");

的方式,去获得根节点其下的子节点的,暂时规避此问题,继续去写我的其他代码的。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值