在XML标签之间提取多个值
我有一个来自Tripadvisor页面的XML文件,它显示了特定区域的餐厅。在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>
区块的所有菜肴。
谢谢!
这是一个基本的bash脚本(使用AWK),没有工作,至少为你提供的示例:
#!/bin/bash
cat in.xml | awk '
/item cuisine/ {item=gensub(/<[^>]*>/, "", "g");
ans = (ans=="") ? item : ans ", " item;}
END {print ans}' > out.txt
脚本删除括号内的所有文本以及它们之间仅保留文本,只在包含“物品美食”的线上。
然而,注意,这是从一个XML文件中提取值的非常脆弱的方式,或者,就此而言,任何数据交换格式(如JSON,YAML等),并可能停止工作十几种不同的原因(坏XML格式,包含括号外的“项目美食”一词的XML行,未被换行符分隔的XML标签等)。
人们总是可以扩展上面的脚本并覆盖越来越多的错误,但没有必要重新发明轮子,因为这已经以更好的方式完成了。像xmllint或xgrep这样的工具提供了更强大的XML解析功能,让您只专注于手边的任务而不是错误处理。
如果这不仅仅是一个快速的个人黑客/实验,我会敦促你使用已有的工具之一。
谢谢,我一定会研究专门用于XML解析的工具,谢谢! – Bob
使用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%, }"
做一些研究XML处理工具,如[标签:xmlstarlet]或[标签:xmllint],或语言如Python或Ruby与固体XML解析库。 –
真的XML或HTML? (这很重要,因为虽然基线HTML *看起来像XML,但它不太合规,所以广泛使用的工具不会接受它)。 –
我已投票结束此问题,因为它似乎是建议使用工具或解决方案的请求,而不是您自己的代码的协助请求。这使您的问题脱离了StackOverflow。如果该评估不正确,并且确实需要编写自己的代码,请[将您的工作添加到您的问题中](https://stackoverflow.com/posts/45309055/edit),然后我会很高兴地收回我的近距离投票。 – ghoti