#xml #xpath #xpath-1.0
#xml #xpath #xpath-1.0
Вопрос:
У меня возникают серьезные проблемы при попытке понять магию XPath.
В принципе, у меня есть такой XML:
<a>
<b>
<c/>
</b>
</a>
Теперь я хочу посчитать, сколько у нас B, без C. Это можно легко сделать с помощью следующего XPath:
count(*/b[not(descendant::c)])
Теперь вопрос прост: как мне сделать то же самое, игнорируя любые пространства имен?
Я бы предположил, что это было что-то вроде этого?
count(*/[local-name()='b']/[not(descendant::[local-name()='c'])])
Но это неверно. Каким будет эквивалентный XPath, как у меня выше, но который игнорирует пространства имен?
Комментарии:
1. Если вы спрашиваете конкретно о XPath 1.0, пожалуйста, проясните это в своем вопросе. В XPath 2.0 и 3.0 вы можете написать *:c для выбора элементов с локальным именем c в любом пространстве имен.
2. OP явно обозначил вопрос как xpath-1.0, но я, вероятно, должен был представить это в правке заголовка, которую я сделал. Исправлено.
3. Хорошо, я виноват. Я предположил, что достаточно пометить тему как xpath-1.0. Я обязательно добавлю это в тему в следующий раз.
Ответ №1:
Данный XPath,
count(*/b[not(descendant::c)])
можно переписать, чтобы игнорировать пространства имен следующим образом:
count(*[local-name()='b' and not(descendant::*[local-name()='c'])])
Обратите внимание, что обычно лучше не уничтожать пространства имен, а правильно работать с ними, назначая префиксы пространства имен и используя их в вашем выражении XPath.
Комментарии:
1. Милая, спасибо! Пришлось потратить немного больше времени, задаваясь вопросом, когда реальный сценарий имеет несколько элементов до этого решения, но в конце концов я туда попал. И я слышал о пространствах имен, но в этом случае мы проверили XML-способ перед этой частью. По сути, это просто проверка кода, которую мы специально не хотим делать зависящей от пространства имен.