如何在java中的嵌套XML中获取父标记?

时间:2018-01-22 22:54:31

标签: java xml parsing xpath xml-parsing

我有一个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>    

我能够遍历列表并获得&#34; name&#34;列表中的值。我应该在CSV文件中打印结果,该文件包含诸如&#34;名字&#34;等列。和&#34;第二个名字&#34;所以在我阅读这些名字的时候,我需要知道哪个名字与哪个名字相关联,以及#34;父母&#34;标签。换句话说,我需要在标签下插入名称&#34; First&#34;在&#34;名字&#34;列和名称在&#34; second&#34;标记在&#34;第二个名称&#34;。 因此,当我循环时,我应该检查父母是否是&#34;首先&#34;将名称插入&#34;名字&#34;等等。  我的名字元素如下:

  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());
        }
   }

如果我使用以下内容进行检查,它会给我&#34; member1&#34;。

  nElement.getParentNode().getNodeName()

我怎样才能得到&#34;第一&#34;或&#34;秒&#34;作为&#34;姓名&#34;的父母?或者有更好的方法吗?

注意:上面的代码是我的代码的一部分,它非常大,因为这个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和y上打印x,在迭代2上打印z!我该如何解决这个问题?

注意:我已使用最近的更改更新了代码,但仍存在相同的问题,并出现如下错误:

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

2 个答案:

答案 0 :(得分:1)

您可以使用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()的第一个参数是当前的“node”而不是“doc”。

答案 1 :(得分:0)

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

BEGIN TRANSACTION
UPDATE [YourTable] SET EndDate = DATEADD(DAY, -1, t.MaxDate)
FROM  
(  
    SELECT StudentID, MAX(StatusEffectiveDate) as MaxDate
    FROM [YourTable]
    GROUP BY StudentID
) t  
WHERE [YourTable].StudentID = t.StudentID AND [YourTable].StatusEffectiveDate <> t.MaxDate

-- COMMIT TRANSACTION
-- ROLLBACK TRANSACTION