我知道我的问题包括2个问题......
首先,我想使用xmllint输出“loc”内容标签。我加载的站点地图有一个xmlns =“...”。
在xmllint shell上,我需要这样做:
setrootns
xpath //defaultns:loc
有效......没问题。但我需要在bash脚本中执行此操作。
(AFAIK)xmllint没有选择告诉“让我们去,setrootns”所以我不能这样做:
xmllint --xpath "//loc" sitemaps.xml
# or
xmllint --xpath "//defaultns:loc" sitemaps.xml
这是第一个问题,如何告诉xmllint加载默认的ns?
如果我不能,让我们来看看我的第二个解决方案:
我可以删除xmlns属性然后,没有ns可以使用:
xmllint --xpath "//loc" <(sed -r 's/xmlns=".*?"//' sitemaps.xml)
但是......现在......我的500个“loc”内容的整个响应被连接成一行!...
我也试过了:
xmllint --shell sitemaps.xml <<EOF
setrootns
xpath //defaultns:loc/text()
EOF
或者再次
xmllint --shell sitemaps.xml <<EOF
setrootns
cat //defaultns:loc
EOF
第一个给我(例如)
465 TEXT
content=http://...
带截断的网址
第二个给了我“------”每两行...和一个“/&gt;”在最后一行...
我开始非常紧张...... :)
非常感谢您找到任何解决方案。
目标是拥有每个位置,每行一个。
答案 0 :(得分:4)
我曾经做过类似的事情:
clean_xml_message=$(echo "$xml_message" | sed 's/xmlns/ignore/')
最终你可以尝试放回新行:
sed 's/></>\n</g'
我猜你只想要没有<loc></loc>
的网址?
然后我会用xmllint选择所有loc元素:
<loc>...</loc><loc>...</loc><loc>...</loc>
然后添加新行:sed 's/<loc>/<loc>\n/g' | sed 's#</loc>#\n</loc>#g'
<loc>
...
</loc><loc>
...
</loc><loc>
...
</loc>
最后删除标记grep -v "<loc>" |grep -v "</loc>"
或单个grep -v "$<"
可以执行此操作。 (-v是反转选择:http://unixhelp.ed.ac.uk/CGI/man-cgi?grep)
答案 1 :(得分:4)
@BrnVrn是对的,我只需要在标签
之后追加“\ n”然后我找到了关于命名空间的答案,我可以使用local-name来检查默认命名空间
所以,我这样做了:
xmllint --xpath "//*[local-name()='loc']/text()" <(sed 's/<loc>/<loc>\n/g' sitemaps.xml)
它有效!
感谢所有
答案 2 :(得分:0)
对于换行问题,您可以查看此仓库:
https://gitlab.gnome.org/cykerway/libxml2
及其合并请求:
https://gitlab.gnome.org/GNOME/libxml2/merge_requests/8
基本上,它使您可以选择xpath节点集结果中的分隔符。因此,有了这个example.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<menu>
<food>
<name>Hot Chocolate</name>
<price>$1.99</price>
</food>
<food>
<name>Iced Tea</name>
<price>$2.99</price>
</food>
</menu>
您可以这样做:
# xmllint --xpath "//name/text()" --xpath-separator "\n" example.xml
输出:
Hot Chocolate
Iced Tea