используя переменные в perl xpath find - PullRequest
1 голос
/ 17 декабря 2010

Хорошо, я искал вокруг и не могу найти ответ на мою проблему. Я использую Perl для анализа XML-файла, используя XPATH. Часть файла, я не знаю, как будут названы дочерние узлы. Например:

<state xmlns="http://google.com" id=1>
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id=2>
  <randomName2 type="boolean">1</randomName2>
</state>

Итак, для каждого randomName мне нужно получить имя, которое я смог сделать, выполнив следующий код (примечание: я получаю список узлов в родительском выражении foreach).

my $elements = $nodes->getChildNodes;

foreach my $element(@$elements)
{
my $name = (lc($element->getName))
}

Моя проблема возникает, когда я пытаюсь получить значение, я пытался поместить my $value = $element->string_value; в цикл foreach, и все, что он делал, возвращало 0 независимо от имени. Я также безуспешно пытался поместить переменную в оператор xpath string_value.

Есть ли способ поместить переменную в выражение xpath? Что-то похожее на (примечание: это не работает) мой $value = $element->find('$name')->string_value;?

Извините, если это не ясно, и я постараюсь ответить на любые вопросы, но любая помощь будет принята с благодарностью, я уже потратил больше времени на попытки выяснить это.

Ответы [ 4 ]

2 голосов
/ 17 декабря 2010

Проблема заключается в том, что если документ находится в пространстве имен по умолчанию, то при использовании имени элемента на шаге расположения ничего не будет выбрано, поскольку XPath обрабатывает все нефиксированные имена как «нет пространства имен». Это наиболее часто задаваемые вопросы в XPath. Просто найдите «Пространство имен XPath по умолчанию», чтобы получить ответ.

Существует два решения :

  1. Зарегистрируйте пространство имен в объекте, подобном «NamespaceManager» и , затем используйте префикс в выражении XPath .

  2. Используйте шаг местоположения как : *[name()='someName']

1 голос
/ 17 декабря 2010

спасибо всем, кто написал ответ, оказывается, я просто дебил. в способе, которым я вызывал подпрограмму, он только правильно передавал переменные для каждого другого набора, поэтому my $value = $element->string_value; выполнял свою работу и возвращал только 0, потому что наборы, в которых было значение 1, передавались.

мои извинения за потраченное время ... не первое впечатление, которое я хотел сделать сообществу stackoverflow, но еще раз спасибо за ответы.

1 голос
/ 17 декабря 2010

Я рекомендую использовать модуль XML :: XPath:

use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => 'test.xml');
my $nodeset = $xp->find('/states/state/*'); # find all subnodes

foreach my $node ($nodeset->get_nodelist) {
    print "FOUND: ", XML::XPath::XMLParser::as_string($node), "\n";
}

с этим примером XML-файла:

<?xml version="1.0"?>

<states>
<state xmlns="http://google.com" id="1">
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id="2">
  <randomName2 type="boolean">1</randomName2>
</state>
</states>

Этот фрагмент кода печатается:

FOUND: <randomName1 type="boolean">0</randomName1>
FOUND: <randomName2 type="boolean">1</randomName2>

Perl + Cpan пород!

1 голос
/ 17 декабря 2010

С префиксом g, связанным с http://google.com URI пространства имен, вы можете использовать это выражение для выбора любого дочернего элемента state:

//g:state/*

Примечание: Если известно, что схема не начинается с оператора //, используйте полный путь.

Обновление: Получить строковое значение каждого из выбранных узлов не проблема XPath, а проблема метода DOM на языке хоста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...