나는 다음 명령을 사용하고 있습니다 :
xmllint --xpath 'substring-after(string(//item/link), "_")' rss.xml
원하는 출력을 얻지만 첫 번째 요소에 있습니다. 이 문제를 각각에 적용하려면 어떻게 해결해야 합니까 link
?
샘플 입력을 허용하고 표현식을 사용하여 원하는 출력을 얻을 수 있는 모든 유틸리티를 기꺼이 사용하겠습니다.
입력 예:
<rss version="2.0">
<channel>
<title>Malicious IPs | By Last Bad Event | Project Honey Pot</title>
<link><![CDATA[http://www.projecthoneypot.org/list_of_ips.php]]></link>
<description/>
<copyright>Copyright 2021 Unspam Technologies, Inc</copyright>
<language>en-us</language>
<lastBuildDate>July 03 2021 07:15:12 PM</lastBuildDate>
<image>
<url>http://www.projecthoneypot.org/images/small_phpot_logo.jpg</url>
<title>Project Honey Pot | Distribute Spammer Tracking System</title>
<link>http://www.projecthoneypot.org</link>
</image>
<item>
<title>92.204.241.167 | C</title>
<link>http://www.projecthoneypot.org/ip_92.204.241.167</link>
<description>Event: Bad Event | Total: 3,061 | First: 2021-03-27 | Last: 2021-07-03</description>
<pubDate>July 03 2021 07:15:12 PM</pubDate>
</item>
<item>
<title>181.24.239.244</title>
<link>http://www.projecthoneypot.org/ip_181.24.239.244</link>
<description>Event: Bad Event | Total: 1 | First: 2021-07-03 | Last: 2021-07-03</description>
<pubDate>July 03 2021 07:15:12 PM</pubDate>
</item>
<item>
<title>193.243.195.66 | S</title>
<link>http://www.projecthoneypot.org/ip_193.243.195.66</link>
<description>Event: Bad Event | Total: 4 | First: 2021-06-12 | Last: 2021-07-03</description>
<pubDate>July 03 2021 07:15:12 PM</pubDate>
</item>
</channel>
</rss>
원하는 출력:
92.204.241.167
181.24.239.244
193.243.195.66
현재 출력:
92.204.241.167
답변1
사용 xmlstarlet
:
xmlstarlet sel -t -m '//item/link' -v 'substring-after(., "_")' -nl rss.xml
이는 먼저 -m
모든 //item/link
노드와 일치( )한 다음 -v
일치된 노드 값( )에서 첫 번째 밑줄 문자 다음에 오는 문자열과 연결된 값을 가져옵니다. 마지막으로 -nl
각 결과 문자열 사이에 개행 문자를 출력합니다.
substring-after()
두 번째 표현식( )은 첫 번째 표현식과 일치하는 컬렉션의 각 노드에 대해 평가됩니다.
답변2
실제로 XPath 1.0만으로는 불가능합니다. XPath 1.0에는 그러한 데이터 유형이 없기 때문에 일련의 문자열을 반환할 수 없으며 중간 결과로 일련의 하위 문자열이 여전히 필요하고 다시 말하지만 그러한 유형이 없기 때문에 개별 하위 문자열을 연결하는 단일 문자열을 반환할 수 없습니다. 데이터. 따라서 XPath 2.0 이상으로 마이그레이션해야 하거나 여러 XPath 표현을 수행하는 호스트 언어의 도움이 필요합니다. 이것이 @Kusalananda의 xmlstarlet 솔루션이 수행하는 작업입니다.
그러나 명령줄을 사용하므로 선택할 수 있는 도구가 매우 다양합니다. XPath를 사용하는 것처럼 쉽게 XQuery를 사용할 수 있으며 확실히 고대 XPath 1.0 버전에 국한되지 않습니다. 예를 들어 Saxon의 경우 다음을 수행할 수 있습니다.
java net.sf.saxon.Query -qs:"//item/link!substring-after(., '_')" -s:rss.xml
이는 XPath 3.0 및 XQuery 3.0에서 사용할 수 있는 "뱅" 연산자를 사용합니다. 이 연산자는 왼쪽 표현식에 의해 선택된 각 항목에 오른쪽 표현식을 적용합니다.
답변3
내 거히델최신 XPath 표현식을 실행하기 위한 또 다른 도구입니다.
xidel rss.xml --xpath "//item/link/substring-after(., '_')"