簡體   English   中英

多次分析XML文件並將結果合並在一起

[英]Parsing XML file more than once and merging the results together

我有一個解析2個XML的子例程,一個是原始日志數據,另一個是過濾器。 我想從其中一個過濾器中找不到的log.xml中刪除所有內容。

這是我的日志文件的示例:

<log>
  <message>
    <type>warning</type>
    <from>cody</from>
    <content>cant use XML::Merge</content>
  </message>
  <message>
    <type>error</type>
    <from>cody</from>
    <content>some text here</content>
  </message>
  <message>
    <type>warning</type>
    <from>charlie</from>
    <content>ruff</content>
  </message>
  <message>
    <type>error</type>
    <from>cody</from>
    <content>an error</content>
  </message>
</log>

帶有如下所示的filter.xml:

<filters>
  <filter>
    <type>warning</type>
    <content>XML::Merge</content>
  </filter>
  <filter>
    <type>error</type>
  </filter>
</filters>

這將導致包含內容“ XML :: Merge”的所有警告被保留,並且所有錯誤也將保留。 我的嘗試是使用第一個過濾器進行第一次通過,這導致所有其他消息節點被斬斷,因此在生成的XML文件中沒有任何錯誤。 然后,下一個過濾器將第一個過濾器應保留的內容截去。 這是我的代碼,如果filter.xml中只有一個過濾器,則可以很好地工作。

sub include {
  my $filterParser = XML::LibXML->new->parse_file($filterXML);
  my $logParser = XML::LibXML->new->parse_file($xml);

  foreach my $filter ( $filterParser->findnodes('/filters/filter') ) {
    foreach my $msg ( $logParser->findnodes('/log/message') ) {
        foreach my $msgNode ($msg->childNodes) {
            foreach my $filterNode ($filter->childNodes) {
                if ($msgNode->localName eq $filterNode->localName) {
                    my $m = $msgNode->textContent;
                    my $f = $filterNode->textContent;
                    if (index($m, $f) == -1) {
                        $msg->parentNode->removeChild($msg);
                    }
                }   
            }
        }
    }
  } 
  $logParser->toFile($xml);
}

我知道為什么它輸出帶有多個過濾器的空白文檔,但是需要幫助將第一遍保存在某個地方,然后使用原始XML與第二個過濾器進行遍歷,依此類推,直到沒有剩下任何過濾器為止將所有內容合並為一個XML,沒有重復的消息。

我想我可能對這個問題的稱呼很差,但是希望這種推論和回答有一天能對其他人有所幫助。 無論如何,我已經用某種蠻力實現了我的目標...我最終為每個過濾器進行了一次遍歷,然后將要保留的節點添加到列表中(我需要一個標志,因為某些過濾器具有多個單一條件)。 在所有消息上處理完所有過濾器之后,我將遍歷log.xml並查找保存在列表中的每個節點。 如果log.xml中的節點與列表中的任何節點都不匹配,則將其從樹中刪除。

sub include {
  my $filterParser = XML::LibXML->new->parse_file($filterXML);
  my $logParser = XML::LibXML->new->parse_file($xml);

  my $remove = true;
  my @nodes;

  foreach my $msg ( $logParser->findnodes('/TdsMainLog/message') ) {
    foreach my $filter ( $filterParser->findnodes('/filters/filter') ) {
        foreach my $msgNode ($msg->childNodes) {
            foreach my $filterNode ($filter->childNodes) {  
                if ($msgNode->localName eq $filterNode->localName) {
                    my $m = $msgNode->textContent;
                    my $f = $filterNode->textContent;
                    if ( index($m, $f) != -1 ) {
                        #mark for keeping
                        $remove = false;
                    } 
                    else { $remove = true; } #else unmark
                }
            }
        }
        if ($remove eq false) { push (@nodes, $msg); }
        $remove = true;
    }
  }

  foreach my $msg ( $logParser->findnodes('/TdsMainLog/message') ) {
    $remove = true;
    foreach my $node (@nodes) {
        if ($msg->isSameNode($node)) {
            $remove = false;
        }
    }
    if ($remove eq true) { $msg->parentNode->removeChild($msg); }
  }
    $logParser->toFile($xml);
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM