#xml #xslt #xmlstarlet
#xml #xslt #xmlstarlet
Вопрос:
Я хотел бы заменить часть URL на XMLStarlet.
http://example.com:8081
Для http://example2.com
XML:
<SHOP>
<SHOPITEMS>
<SHOPITEM>
<IMGURL>http://example.com:8081/image.jpg</IMGURL>
<IMAGES>
<IMGURL>http://example.com:8081/image2.jpg</IMGURL>
<IMGURL>http://example.com:8081/image3.jpg</IMGURL>
</IMAGES>
</SHOPITEM>
</SHOPITEMS>
</SHOP>
Как вы можете видеть, текст, который я хотел бы заменить, находится на нескольких уровнях в:
/SHOP/SHOPITEMS/SHOPITEM/IMGURL
/SHOP/SHOPITEMS/SHOPITEM/IMAGES/IMGURL
До сих пор я пытался:
xmlstarlet ed -u "//SHOP/SHOPITEMS/SHOPITEM/IMGURL/*[starts-with(text(), 'http://example.com:8081')]" -v http://example2.com input.xml
не сработало … и:
xmlstarlet ed -u "//SHOP/SHOPITEMS/SHOPITEM/IMGURL/text()" -x "str:replace(., 'http://example.com:8081', 'http://example2.com')" input.xml
xmlXPathCompOpEval: function replace not found
Unregistered function
Segmentation fault
Любая помощь приветствуется.
Комментарии:
1. XMLStarlet использует libxslt, и с тех пор, как функция
str:replace()
EXSLT была удалена из libxslt в 2013 году, она была недоступна. Возможно, вы могли бы подумать о том, чтобы сделать что-то вродеsed '/<IMGURL>/s/(example).com:8081/12.com/' input.xml
или альтернативу awk, напримерawk '/<IMGURL>/{sub("example.com:8081", "example2.com")}1' input.xml
.2. Почему это помечено как
xslt
?
Ответ №1:
Не настоящая замена, а трюк с подстрокой. По крайней мере, это работает:
xmlstarlet ed -u "//*[starts-with(text(),'http://example.com:8081/')]" -x "concat('http://example2.com/',substring(text(),25))" input.xml