【问题标题】:Attempt to get next and previous sibling of a node after parsing xml for a specific node using java在使用 java 为特定节点解析 xml 后尝试获取节点的下一个和上一个兄弟节点
【发布时间】:2015-02-01 15:50:58
【问题描述】:

我有一个 xml,其中包含 1000 个事件的日志,其中每个事件都有一个键, 我的目标是当用户搜索事件键时,我应该向他显示具有该键的事件节点的 xml 并准备上一个和下一个兄弟的信息。

xml结构如下:

<LOG>
   <EVENT_SET>
      <DOCGET system="T610_00" fingerPrint="NO_SIGNATURE">
         <event>
            <key>382</key>
            <date>2015-01-28T09:15:15.350+0000</date>
            <service>CORE</service>
            <class>APPLICATION</class>
         </event>
         <document>
            <docuri>getdocs:///DocMapCSDOCS.dPortal/1</docuri>
            <sign_info>
               <signature>VqtR9Gpny/MPE43/5o4hJXp8bR7gbsVUJqHlTI+VfztMSQecTpZwAQpxmorrdBJKvmn+h7eZzV1geVodkVECvOjQMRmRbnpT6mrpbiXxjDOsZsQRDNemTYUKETrQFIBRtXcjoP61une1LOsS5C749ehwbZ1jEaNH6fPjH4n+OH4=</signature>
            </sign_info>
         </document>
      </DOCGET>
      <DOCGET system="T610_00" fingerPrint="NO_SIGNATURE">
         <event>
            <key>383</key>
            <date>2015-01-28T09:15:18.310+0000</date>
            <service>CORE</service>
            <class>APPLICATION</class>
         </event>
         <document>
            <docuri>getdocs:///DocMapCSDOCS.dPortal/2</docuri>
            <sign_info>
               <signature>VqtR9Gpny/MPE43/5o4hJXp8bR7gbsVUJqHlTI+VfztMSQecTpZwAQpxmorrdBJKvmn+h7eZzV1geVodkVECvOjQMRmRbnpT6mrpbiXxjDOsZsQRDNemTYUKETrQFIBRtXcjoP61une1LOsS5C749ehwbZ1jEaNH6fPjH4n+OH4=</signature>
            </sign_info>
         </document>
      </DOCGET>
      .......
  </EVENT_SET>
</LOG>

到目前为止,我获取密钥节点的代码是:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
//parsing the xml file
journaldoc = builder.parse(journalFile);
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath xpath = xpathfactory.newXPath();

//xpath to search for the event having the key requated by the user
String sXpath = "//DOCGET[event/key='"+eventkey+"']";
XPathExpression expr = xpath.compile(sXpath);
Object result = expr.evaluate(journaldoc, XPathConstants.NODE);
Node eventnode = (Node) result;

//return to the user the xml part with root DOCGET, and having the key requested
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Node copyNode = document.importNode(eventNode, true);
document.appendChild(copyNode);
DOMImplementationLS domImplementationLS = (DOMImplementationLS) document.getImplementation();
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
String xmlNode =  lsSerializer.writeToString(document);

现在我需要获取此节点的上一个和下一个兄弟节点并获取它们的键,以便将它们保存在 HashMap 中。

问题是在执行 eventnode.getPreviousSibling 和 eventnode.getNextSibling 时,我得到了损坏的信息,我无法获得这些事件的密钥。

有人有更好的主意吗?

谢谢你, 卡琳

【问题讨论】:

    标签: java xml xpath siblings nextsibling


    【解决方案1】:

    我认为您正在寻找 XPath 轴 preceding-siblingfollowing-sibling。这些选择同一级别的所有节点,所以如果你只想要下一个邻居,你需要添加一个谓词来选择第一个:following-sibling::*[1]。但是您只需要事件节点,并且事件节点不是直接的兄弟姐妹,而是 &lt;DOCGET&gt; 元素。因此,您需要从一个事件节点向上,找到下一个/上一个兄弟节点并再次向下。这归结为这个表达式:../preceding-sibling::*[1]/event 在事件节点上进行评估。

    您可以通过使用data projection(披露:我隶属于该项目)对事件进行面向对象的访问来简化任务,但仍将 Java 代码结构与 XML 结构分离:

    public class ReadEvents {
    
    public interface Event {
        @XBRead("./key")
        String getKey();
    
        @XBRead("./date using yyyy-MM-dd'T'HH:mm:ss.SSSZ")
        Date getDate();
    
        @XBRead("../document/docuri")
        String getDocumentURI();
    
        @XBRead("../preceding-sibling::*[1]/event")
        Event getPreviousEvent();
    
        @XBRead("../following-sibling::*[1]/event")
        Event getNextEvent();
    }
    
    public static void main(String... args) {
        List<Event> allEvents = new XBProjector().io().url("res://log.xml").evalXPath("//event").asListOf(Event.class);
        for (Event event : allEvents) {
            System.out.print(event.getDate()+ ": Event " + event.getKey());
            if (event.getPreviousEvent() != null) {
                System.out.print(" previous event has key " + event.getPreviousEvent().getKey());
            }
            if (event.getNextEvent() != null) {
                System.out.print(" next event has key " + event.getNextEvent().getKey());
            }
            System.out.println();
        }
      }
    }
    

    对于你的例子,这个程序打印出来:

    Wed Jan 28 10:15:15 CET 2015: Event 382 next event has key 383
    Wed Jan 28 10:15:18 CET 2015: Event 383 previous event has key 382
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多