gpt4 book ai didi

xml - 使用 block 中的 xmlstarlet 从同一节点获取多个子注释

转载 作者:行者123 更新时间:2023-12-03 10:00:16 25 4
gpt4 key购买 nike

我有一个 XML 文件,其中包含多个用户条目,其中包含一些用户数据,如姓名、电子邮件和其他数据。这似乎可以使用多个 --value-of 来完成。 ( -v ) 参数如下:

$ xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t --nl -v "//n:title" -v "//n:email" ~/tests/test-xml.xml

Some user
Some user #2
Some user #3some.user@example.com
some.user2@example.com
some.user3@example.com
但是他们不在一起,看起来工具进程都是 <title>先是元素,然后是所有 <email>那些。我喜欢有以下格式:
Some user
some.user@example.com
Some user #2
some.user2@example.com
...
发现我需要 xpath 函数 concat为了这。现在我至少用逗号分隔它们:
$ xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t -m "//n:entry" -v "concat(current()//n:title, ',', current()//n:email)" ~/tests/test-xml.xml
Some user,some.user@example.comSome user #2,some.user2@example.comSome user #3,some.user3@example.com
这正是我需要的,但是当我设置 \n 时作为分隔符而不是 , ,它只会打印 \n而不是换行。 \\n 也是如此和 \r\n .作为一种解决方法,这可以使用 sed 替换,如下所示: sed 's/,/\n/g'但是,这并不能解决 some.user@example.comSome user #2之间没有换行的问题。 :
$ xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t -m "//n:entry" -v "concat(current()//n:title, ',', current()//n:email)" ~/tests/test-xml.xml | sed 's/,/\n/g'
Some user
some.user@example.comSome user #2
some.user2@example.comSome user #3
some.user3@example.com
我怎么能意识到这一点?更喜欢没有额外的解决方案 sed命令,如果它有意义并且是可能的。
解决方法
我发现的唯一解决方法是将它嵌套在另一个 concat 中调用添加另一个字符,该字符标识需要另一个新行的位置,可以替换为 \n太像这样:
$ xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t -m "//n:entry" -v "concat(concat(current()//n:title, ',', current()//n:email), '|', '')" ~/tests/test-xml.xml | sed -E 's/[,|]+/\n/g'
Some user
some.user@example.com
Some user #2
some.user2@example.com
Some user #3
some.user3@example.com
尽管这有效,但对我来说似乎是一个讨厌的解决方法。想知道是否有更干净的方法来做到这一点。我想可以通过更深入的体验 xmlstarlet也许还有 xpath .
测试 XML 文档
<?xml version="1.0" encoding="UTF-8"?>
<feed
xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app"
xmlns:snx="http://www.ibm.com/xmlns/prod/sn"
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
<opensearch:totalResults
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">67
</opensearch:totalResults>
<opensearch:startIndex
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">1
</opensearch:startIndex>
<opensearch:itemsPerPage
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">100
</opensearch:itemsPerPage>

<entry>
<title>Some user</title>
<contributor>
<email>some.user@example.com</email>
</contributor>
</entry>

<entry>
<title>Some user #2</title>
<contributor>
<email>some.user2@example.com</email>
</contributor>
</entry>

<entry>
<title>Some user #3</title>
<contributor>
<email>some.user3@example.com</email>
</contributor>
</entry>

</feed>

最佳答案

最简单的方法是在每个 --nl 之后输出一个换行符( entry ) :

xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t -m "//n:entry" -v "n:title" --nl -v "n:contributor/n:email" --nl input.xml
但这将在输出结束时输出一个额外的换行符:
Some user
some.user@example.com
Some user #2
some.user2@example.com
Some user #3
some.user3@example.com

另一种方法是在 entry 之前输出换行符如果不是第一个。 (使用 -i (xsl:if) 和 -b (中断嵌套))...
xmlstarlet sel -N n="http://www.w3.org/2005/Atom" -t -m "//n:entry" -i "position() > 1" --nl -b -v "n:title" --nl -v "n:contributor/n:email" input.xml
输出:
Some user
some.user@example.com
Some user #2
some.user2@example.com
Some user #3
some.user3@example.com

关于xml - 使用 block 中的 xmlstarlet 从同一节点获取多个子注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64594096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com