我有一个来自Tripadvisor页面的XML文件,它显示了特定区域内的餐馆。
我想从搜索结果中提取所有餐厅提供的'美食'。所有值都存储在<a>
和<span>
HTML标记之间。
对于每家餐厅,数据存储在<div>
标签之间,来自一家餐厅的美食片段如下所示:
<div class="cuisines">
<span class="item price">££ - £££</span>
<span class="item cuisine" onclick="ta.restaurant_list_tracking.clickNonLinkedCuisine()">Bar</span>
<a class="item cuisine" href="/Restaurants-g1096751-c7-Whittlebury_Northamptonshire_England.html" onclick="ta.setEvtCookie('RESTAURANT_DETAILS', 'RESTAURANTS_DETAILS_CUISINE', '', 0, this.href);">British</a>
<span class="item cuisine" onclick="ta.restaurant_list_tracking.clickNonLinkedCuisine()">Pub</span>
<span class="item cuisine" onclick="ta.restaurant_list_tracking.clickNonLinkedCuisine()">Gastropub</span>
<a class="item cuisine" href="/Restaurants-g1096751-zfz10665-Whittlebury_Northamptonshire_England.html" onclick="ta.setEvtCookie('RESTAURANT_DETAILS', 'RESTAURANTS_DETAILS_CUISINE', '', 0, this.href);">Vegetarian Friendly</a>
<a class="item cuisine" href="/Restaurants-g1096751-zfz10992-Whittlebury_Northamptonshire_England.html" onclick="ta.setEvtCookie('RESTAURANT_DETAILS', 'RESTAURANTS_DETAILS_CUISINE', '', 0, this.href);">Gluten Free Options</a>
</div>
如何在每个餐厅的这些div
标签之间提取美食,然后将其输出到新的文本文件中?
我希望从该代码片段获得的预期输出是:
Bar, British, Pub, Gastropub, Vegetarian Friendly, Gluten Free Options
请注意,此XML文件中有多个<div>
标记,我想要处理所有这些标记,将所有不同菜系的结果提取到一个文本文件中。每行显示每个<div>
块的所有美食。
谢谢!
答案 0 :(得分:0)
这是一个基本的bash脚本(使用awk)完成这项工作,至少对于你提供的例子:
#!/bin/bash
cat in.xml | awk '
/item cuisine/ {item=gensub(/<[^>]*>/, "", "g");
ans = (ans=="") ? item : ans ", " item;}
END {print ans}' > out.txt
该脚本会删除括号内的所有文本,并仅保留它们之间的文本,并且仅保留在包含&#34; item cuisine&#34;的行中。
但是,请注意,这是从XML文件中提取值的非常脆弱方式,或者就此而言,任何数据交换格式(如JSON,YAML)等等,并且可能因为十几种不同的原因而停止工作(错误的XML格式,包含&#34;项目菜单的XML行和#34;括号外的术语,不用新行分解的XML标记等)。
总是可以扩展上面的脚本并覆盖越来越多的错误,但是没有必要重新发明轮子,因为这已经以更好的方式完成了。像xmllint或xgrep这样的工具提供了更强大的XML解析功能,让您只关注手头的任务而不是错误处理。
如果这不仅仅是一个快速的个人黑客/实验,我恳请您使用已有的工具之一。
答案 1 :(得分:0)
使用XMLStarlet,假设您的内容位于in.xml
:
# Generate an array of cuisines
cuisines=( )
while IFS= read -r cuisine; do
cuisines+=( "$cuisine" )
done < <(xmlstarlet sel -t \
-m '//div[@class="cuisines"]/*[@class="item cuisine"]' \
-v . -n \
<in.xml)
# Transform that into a string with a command and space after each item
printf -v cuisines_str '%s, ' "${cuisines[@]}"
# Remove the trailing ", " from that string on output
echo "${cuisines_str%, }"