Замените часть URL-адреса в XML на xmlstarlet

#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