【问题标题】:How to get a parent tag in nested XML in java?如何在java中的嵌套XML中获取父标签?
【发布时间】:2018-07-01 16:10:45
【问题描述】:

我有一个如下的 XML 文件:

  <main>
       <member>
           <tag1>
              <id>"123"</id> 
           </tag1>
       </member> 
       <member>
           <tag1>
              <id>"222"</id>
              <first>
                <code>"1"</code>
                <name>"x"<name>
              </first>
           </tag1>
       </member>
       <member>
           <tag1>
               <id>"321"</id> 
           </tag1>
       </member>  
       <member>
           <tag1>
              <id>"333"</id>
              <second>
                <code>"1"</code>
                <name>"y"<name>
              </second>
              <first>
                <code>"2"</code>
                <name>"z"<name>
              </first>  
           </tag1>
       </member> 
  </main>    

我能够遍历列表并在列表中获取“名称”值。我应该在一个 CSV 文件中打印结果,其中包含“名字”和“第二个名字”等列,所以在我阅读这些名字时,我需要知道哪个名字与哪个“父”标签相关联。换句话说,我需要在“名字”列的“名字”标签下插入名字,并在“第二个名字”下的“第二个”标签下插入名字。 所以在我循环的时候,我应该检查父母是否是“第一个”,将名字插入“名字”等等。 我的名字元素如下:

  NodeList nameList=doc.getElementsByTagName("tag1");
  ...//some code to parse throught the rest of the elements
  for (int temp = 0; temp < nameList.getLength(); temp++) {
       Node nNode = nameList.item(temp);
       if (nNode.getNodeType() == Node.ELEMENT_NODE){
          Element nElement=(Element) nNode;
          System.out.println(nElement.getElementsByTagName("name").item(temp).getTextContent());
        }
   }

如果我使用以下内容进行检查,它将给我“member1”。

  nElement.getParentNode().getNodeName()

作为“名字”的父母,我怎样才能获得“第一”或“第二”?还是有更好的方法来做到这一点?

注意:上面的代码是我的代码的一部分,它非常大,因为这个 XML 中有很多标签需要解析。我只是添加了信息所需的部分代码。如果需要更多信息,请告诉我,以便我更新我的问题。

我使用 XPath 解决了这个问题,但仍然没有得到答案:

        String expression="/main/member";
        String fExpression="/main/member/tag1/first";
        String sExpression="/main/member/tag1/second";
        NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);


        for (int i=0; i<nodeList.getLength();i++){
            Node nNode=nodeList.item(i);
            NodeList pLangList = (NodeList) xPath.compile(fExpression).evaluate(nNode, XPathConstants.NODESET);
            NodeList sLangList = (NodeList) xPath.compile(sExpression).evaluate(nNode, XPathConstants.NODESET);
            Node flangNode=pLangList.item(i);
            Node slangNode=sLangList.item(i);
            if (flangNode.getNodeType() == Node.ELEMENT_NODE){
                Element fLangElement=(Element) plangNode;
                System.out.println(i+"# primary"+fLangElement.getElementsByTagName("name").item(0).getTextContent());
             }
            if (slangNode.getNodeType() == Node.ELEMENT_NODE){
                 Element sLangElement=(Element) slangNode;
                 System.out.println(i+"# secondary"+sLangElement.getElementsByTagName("name").item(0).getTextContent());
             }
             //rest of the code
        }

我使用了 XPath,但问题是:在从 0 到列表长度的循环中,在迭代 0 中它打印 x 和 y,然后在迭代 1 中打印 z。它应该在迭代 1 上打印 x,在迭代 2 上打印 y, z!我该如何解决?

注意:我已经用最近的更改更新了代码,但仍然有同样的问题加上如下错误:

0# first x
0# second y 
1# first z

【问题讨论】:

    标签: java xml parsing xpath xml-parsing


    【解决方案1】:

    我能够解决这个问题如下:

    NodeList nameList=doc.getElementsByTagName("tag1");
    ...//some code to parse throught the rest of the elements
    for (int temp = 0; temp < nameList.getLength(); temp++) {
       Node nNode = nameList.item(temp);
       if (nNode.getNodeType() == Node.ELEMENT_NODE){
          Element nElement=(Element) nNode;
          int count=getChildElementCount(nElement); //it'll return the number of child nodes if there is any
          if (count==1)
                 System.out.println(temp+" # "+nElement.getElementsByTagName("name").item(0).getTextContent());
          else{
              NodeList childNodes=nElement.getChildNodes();
              int j=0;
              for (int i=0;i<childNodes.getLength();i++){
                    if (childNodes.item(i).getNodeType() == Node.ELEMENT_NODE && j<count){
                                         if(childNodes.item(i).getNodeName().contentEquals("second")){
                                            //do something
                                            j++;
                                         }
                                          if(childNodes.item(i).getNodeName().contentEquals("first")){
                                           //do somehting
                                            j++;
                                         }
                                     }
    
                                 }
                             }
    

    【讨论】:

      【解决方案2】:

      您可以使用 xpath 直接处理所需的元素(java 代码部分是您的全部;))

      获取“成员”标签并对其进行迭代

      String expression = "//member"";
              NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);
      

      然后对于每个节点,获取引用当前节点的其他标签

      String namex = "//tag1/name/text()";
      NodeList namenodeList = (NodeList) xPath.compile(namex).evaluate(nNode, XPathConstants.NODESET);
      

      请注意,evaluate() 的第一个参数是当前的“节点”而不是“文档”。

      【讨论】:

      • 我使用了 XPath,但问题是:在从 0 到列表长度的循环中,在迭代 0 中它打印 x 和 y,然后在迭代 1 中打印 z。它应该在迭代 1 上打印 x,在迭代 2 上打印 y, z!我该如何解决这个问题?
      • 请用您正在测试的实际代码更新您的问题。
      • Luis 感谢您帮助我,我做了更改,但我仍然看到同样的问题,我将使用我最近所做的更改来更新问题。请您看一下并帮我解决这个问题吗?!
      • 1- 名称 xpath 必须更改为相对于当前节点,检查我的答案。 2- 在询问 item(i) 之前,您应该检查 pLanList 列表长度
      • 在您的回答中,您在“evaluate()”的第二部分中放置了“node”,其中第一部分您定义了一个名为“nodeList”的 NodeList 因为我在循环内分配了 plangList,所以我假设每次 nNode 都是由 item(i) 创建的新节点,因此在评估中包含 nNode 听起来像是每次迭代的相对 nNode。
      猜你喜欢
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2018-04-27
      • 2014-05-09
      • 1970-01-01
      相关资源
      最近更新 更多