如何查看xml中的Nodelist hashTag是否被解析?

How to check whether the Nodelist hasTag in xml parsing?

我正在解析一个动态生成的 xml,我对从 xml 中提取数据有一些疑问。我的代码如下,

    try {
      File file = new File("test.xml");
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(file);
      doc.getDocumentElement().normalize();
      System.out.println("Root element " + doc.getDocumentElement().getNodeName());
      NodeList nodeLst = doc.getElementsByTagName("control");
      System.out.println("Information of all fields");

      for (int s = 0; s < nodeLst.getLength(); s++) {

        Node fstNode = nodeLst.item(s);

        if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

          Element fstElmnt = (Element) fstNode;


                  NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
              Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
              NodeList fstNm = fstNmElmnt.getChildNodes();
              System.out.println("Value:  "  + ((Node) fstNm.item(0)).getNodeValue());


                  NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("label");
              Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
              NodeList lstNm = lstNmElmnt.getChildNodes();
              System.out.println("Label: " + ((Node) lstNm.item(0)).getNodeValue());

NodeList hintElmntLst = fstElmnt.getElementsByTagName("hint");
          Element hintElmnt = (Element) hintElmntLst.item(0);
          NodeList hint = hintElmnt.getChildNodes();
          System.out.println("Hint: " + ((Node) hint.item(0)).getNodeValue());

        }

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

我的XML格式

    <metadata>

    <control name="first-name">
    <resources lang="en">
    <label>First Name</label>
    <hint>your first name</hint>

    </resources>
<resources lang="fr">
                            <label>Prénom</label>
                            <help />
                            <hint>
                                    Votre prénom
                            </hint>

                    </resources>
<value> Hari </value>
    </control>


    </metadata>

我有以下问题,

1) 如果相应字段存在提示,则只有 <hint> 将存在于 xml 中,否则它不会退出。因此,如果标签不存在,那么我会收到错误消息。那么我们如何检查标签是否存在呢?如果标签存在,那么我们将获取标签内容。

2) 对于值字段如果字段值不为空那么它将正常工作。如果字段值为 null,则 xml 中的标记将显示为 <value/>,因此如果字段值为 null,我的代码未检测到 <value/> 标记并出现错误。那么如果它带有空值,我如何将字段值设置为null。

有什么建议请..

你只需要检查你得到的元素节点。

如果你有<value />,那么它不会有子节点:

  NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
  Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
  if (fstNmElmnt.hasChildNodes()) {
      NodeList fstNm = fstNmElmnt.getChildNodes();
      System.out.println("Value:  "  + ((Node) fstNm.item(0)).getNodeValue());
  } else {
      System.out.println("Value: null");
  }

如果你没有提示,那么你会得到一个长度为 0 的列表:

  NodeList hintElmntLst = fstElmnt.getElementsByTagName("hint");
  if (hintElmntLst.getLength() > 0) {
      Element hintElmnt = (Element) hintElmntLst.item(0);
      NodeList hint = hintElmnt.getChildNodes();
      System.out.println("Hint: " + ((Node) hint.item(0)).getNodeValue());
  }

评论问题的答案:如果你只想看英文资源,那么简单地在你已有的资源中引入另一个循环:

  NodeList resources = fstElmnt.getElementsByTagName("resources");
  for (int k = 0; k < resources.getLength(); k++) {
      Node resNode = resources.item(k);
      if (resNode.getNodeType() == Node.ELEMENT_NODE) {
          Element resElement = (Element)resNode;
          if (resElement.hasAttribute("lang") &&
                   resElement.getAttribute("lang").equals("en")) {
              //your existing code here for value, label, hint
          }
      }
   }

您只需更改值、标签和提示的代码,以便您只能访问 resElement。例如:

NodeList fstNmElmntLst = resElement.getElementsByTagName("value");

而不是fstElmnt.getElementsByTagName("value");

可以吗?如果我像下面这样改变它;

而不是这个;

          NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
          Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
          NodeList fstNm = fstNmElmnt.getChildNodes();
          System.out.println("Value:  "  + ((Node) fstNm.item(0)).getNodeValue());

将其更改为;

         System.out.println("Value:  " + getTagValue("value", fstElmnt) );

getTagValue 方法是;

private static String getTagValue(String tag, Element eElement) {
    Node nNode = eElement.getElementsByTagName(tag).item(0);
    if (nNode == null) {
        return null;
    }
    NodeList nlList = nNode.getChildNodes();
    Node nValue = (Node) nlList.item(0);
    if (nValue == null)
        return null;
    return nValue.getNodeValue();
}

改为使用 XPath。代码将 更易于阅读和维护:

    XPath xp = XPathFactory.newInstance().newXPath();

    NodeList controls = (NodeList) xp.evaluate("//control", doc,
            XPathConstants.NODESET);
    for (int i = 0; i < controls.getLength(); ++i) {
        Node c = controls.item(i);
        String label = xp.evaluate(".//label", c);
        String hint = xp.evaluate(".//hint", c);
        String value = xp.evaluate(".//value", c);

        System.out.printf("%s, %s, %s\n", label, hint, value);
    }

更新:

要select基于语言,只需在资源元素上包含一个谓词:

        String label = xp.evaluate("resources[@lang='en']/label", c);
        String hint = xp.evaluate("resources[@lang='en']/hint", c);
        String value = xp.evaluate("resources[@lang='en']/value", c);

或者,您当然可以 select 资源元素,然后是每个需要的子元素。