#xml #xpath #text #xmlstarlet
#xml #xpath #текст #xmlstarlet
Вопрос:
У меня есть такие html-файлы. В основном он содержит div, содержащий тексты с одним внутренним диапазоном, а остальная текстовая часть имеет довольно произвольный формат.
<html>
<div>
<span class="c1">Text1</span><br/>
Text4<br/>
Text5
</div>
<div>
<span class="c1">TextA</span><a href="...">TextD</a>
</div>
</html>
тривиально выбирать / печатать только определенный текст внутри span с
xml sel -t -m "/html/div" -v "span[@class='c1']" -n
Однако я не знаю, как выбрать / распечатать остальной текст внутри, но за пределами диапазона, независимо от любых других тегов, таких как <br/>
. Функция text()
работает не так, как я ожидал.
xml sel -t -m "/html/div" -v "concat(span[@class='c1'],'|',text(),'$')" -n
будет вырезать текст за <br/>
тегами.
как я могу получить что-то вроде
Text1|
Text4
Text5$
TextA|TextD$
Ответ №1:
Прошло некоторое время, но вы сказали,
Я хотел бы знать, есть ли лучший способ, чем метод substr
Вот версия, которая выдает вывод в порядке документа, используя шаблон, соответствующий объединению желаемых элементов внутри /html/div
. Другие элементы, чем br
выводятся с их текстовым значением, за которым следует вертикальная полоса. Каждый br
элемент выводится с новой строкой и последующим br
нормализованным текстом. Наконец, после 2 -b
секунд, нарушающих -m
вложенность, каждый div
заканчивается знаком доллара, за которым следует новая строка.
xmlstarlet sel -T -t
-m "/html/div"
-m 'a | br | span[@class="c1"]'
--if 'local-name() = "br"'
-n -v 'normalize-space(following-sibling::text())'
--else -v '.' -o '|'
-b -b -o '
Вывод:
Text1|
Text4
Text5$
TextA|TextD|$
Чтобы удалить последнее |
перед $
заменой -o '|'
на
-v 'substring("|",1,count(following-sibling::*))'
который выдается |
только в том случае, если есть больше родственных элементов.
Чтобы добавить поддержку p
элементов, например, добавьте | p
ко 2-му -m
выражению и добавьте <p>Hello from P</p>
/html/div
в исходный файл.
(Документация --if … --elif … --else …
, э-э, менее чем обильная, но, насколько я могу понять, из кода XSLT, выводимого с помощью -C
опции, --if
предложение завершается -b
.)
Я использовал xmlstarlet
1.6.1.
Ответ №2:
Я протестировал некоторые xpath, поэтому лучший, который я нашел, это
//div/descendant-or-self::*/text()[normalize-space()]
Он указывает на контекстный узел и всех его потомков, получает текстовые значения, которые не являются пустыми.
об оси XPath
Ответ №3:
Я думаю, что есть лучший способ выполнить эту работу, но у меня есть этот. Я протестировал его в scrapy xpath.Я думаю, это поможет вам.
print(data.xpath("concat(string(//div[1]/span[contains(@class, 'c1')]),'|', 'n',substring-before(substring-after(//div[1], 'Text1'), 'Text5'),'n',substring-after(substring-after(//div[1], 'Text1'),'Text4'),'
вывод:
Text1|
Text4
Text5$
TextA|TextD$
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее - это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
xml sel -t -m "/html/div" -v "span[@class='c1']" -o '|' -v "substring-after(.,span[@class='c1'])" -n
но я хотел бы знать, есть ли лучший способ, чем метод substr .
-n
source
Вывод:
Чтобы удалить последнее |
перед $
заменой -o '|'
на
-v 'substring("|",1,count(following-sibling::*))'
который выдается |
только в том случае, если есть больше родственных элементов.
Чтобы добавить поддержку p
элементов, например, добавьте | p
ко 2-му -m
выражению и добавьте <p>Hello from P</p>
/html/div
в исходный файл.
(Документация --if … --elif … --else …
, э-э, менее чем обильная, но, насколько я могу понять, из кода XSLT, выводимого с помощью -C
опции, --if
предложение завершается -b
.)
Я использовал xmlstarlet
1.6.1.
Ответ №2:
Я протестировал некоторые xpath, поэтому лучший, который я нашел, это
Он указывает на контекстный узел и всех его потомков, получает текстовые значения, которые не являются пустыми.
об оси XPath
Ответ №3:
Я думаю, что есть лучший способ выполнить эту работу, но у меня есть этот. Я протестировал его в scrapy xpath.Я думаю, это поможет вам.
вывод:
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее - это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
но я хотел бы знать, есть ли лучший способ, чем метод substr .
, 'n',//div[2]/span[contains(@class, 'c1')]/text(),'|',//div[2]/a/text(),'
вывод:
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее - это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
но я хотел бы знать, есть ли лучший способ, чем метод substr .
-n
source
Вывод:
Чтобы удалить последнее |
перед $
заменой -o '|'
на
-v 'substring("|",1,count(following-sibling::*))'
который выдается |
только в том случае, если есть больше родственных элементов.
Чтобы добавить поддержку p
элементов, например, добавьте | p
ко 2-му -m
выражению и добавьте <p>Hello from P</p>
/html/div
в исходный файл.
(Документация --if … --elif … --else …
, э-э, менее чем обильная, но, насколько я могу понять, из кода XSLT, выводимого с помощью -C
опции, --if
предложение завершается -b
.)
Я использовал xmlstarlet
1.6.1.
Ответ №2:
Я протестировал некоторые xpath, поэтому лучший, который я нашел, это
Он указывает на контекстный узел и всех его потомков, получает текстовые значения, которые не являются пустыми.
об оси XPath
Ответ №3:
Я думаю, что есть лучший способ выполнить эту работу, но у меня есть этот. Я протестировал его в scrapy xpath.Я думаю, это поможет вам.
вывод:
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее — это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
но я хотел бы знать, есть ли лучший способ, чем метод substr .
)»).get())вывод:
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее — это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
но я хотел бы знать, есть ли лучший способ, чем метод substr .
-n
sourceВывод:
Чтобы удалить последнее |
перед $
заменой -o '|'
на
-v 'substring("|",1,count(following-sibling::*))'
который выдается |
только в том случае, если есть больше родственных элементов.
Чтобы добавить поддержку p
элементов, например, добавьте | p
ко 2-му -m
выражению и добавьте <p>Hello from P</p>
/html/div
в исходный файл.
(Документация --if … --elif … --else …
, э-э, менее чем обильная, но, насколько я могу понять, из кода XSLT, выводимого с помощью -C
опции, --if
предложение завершается -b
.)
Я использовал xmlstarlet
1.6.1.
Ответ №2:
Я протестировал некоторые xpath, поэтому лучший, который я нашел, это
Он указывает на контекстный узел и всех его потомков, получает текстовые значения, которые не являются пустыми.
об оси XPath
Ответ №3:
Я думаю, что есть лучший способ выполнить эту работу, но у меня есть этот. Я протестировал его в scrapy xpath.Я думаю, это поможет вам.
вывод:
Комментарии:
1. Я хотел бы найти общий способ. Text1 и так далее — это просто случайный пример.
Ответ №4:
Каким-то образом я нашел решение с substring-after
но я хотел бы знать, есть ли лучший способ, чем метод substr .