[英]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.