У меня есть очень большой XML-документ, который я выполняю. XML использует в основном атрибуты, а не значения узлов. Мне может понадобиться найти множество файлов в файле, чтобы собрать одну группу информации. Они связаны друг с другом с помощью различных значений тега ref. В настоящее время каждый раз, когда мне нужно найти один из узлов для извлечения данных, я перебираю весь XML и выполняю соответствие атрибуту, чтобы найти правильный узел. Есть ли более эффективный способ просто выбрать узел заданного значения атрибута вместо постоянного цикла и сравнения? Мой текущий код настолько медленный, что он почти бесполезен.Perl libXML найти узел по значению атрибута
В настоящее время я делаю что-то подобное много раз в том же файле для множества различных узлов и комбинаций атрибутов.
my $searchID = "1234";
foreach my $nodes ($xc->findnodes('/plm:PLMXML/plm:ExternalFile')) {
my $ID = $nodes->findvalue('@id');
my $File = $nodes->findvalue('@locationRef');
if ($searchID eq $ID) {
print "The File Name = $File\n";
}
}
В приведенном выше примере я выполняю цикл и использую «if» для сравнения ID. Я надеялся, что смогу сделать что-то вроде этого ниже, чтобы просто совместить узел по атрибуту ... и будет ли он более эффективным, чем цикл?
my $searchID = "1234";
$nodes = ($xc->findnodes('/plm:PLMXML/plm:ExternalFile[@id=$searchID]'));
my $File = $nodes->findvalue('@locationRef');
print "The File Name = $File\n";
Упс, исправлена ошибка. – ikegami
Я удивлен, что '//.[@ id]' работает, поскольку '.' представляет текущий контекст и не имеет особого значения, кроме как первый шаг в пути. '// * [@ id]' гораздо чаще встречается – Borodin
@Borodin, это как раз в файловой системе. '/ foo/bar /././ baz' - это то же самое, что'/foo/bar/baz'. Однако '*' соответствует только узлам элемента, тогда как '.' соответствует любому узлу, поэтому' * '- это то, что я должен был использовать. Исправлена. – ikegami