我有从 Gnote 生成的以下 xml:
<?xml version="1.0"?>
<note version="0.3" xmlns:link="http://beatniksoftware.com/tomboy/link" xmlns:size="http://beatniksoftware.com/tomboy/size" xmlns="http://beatniksoftware.com/tomboy"><title>things</title><text xml:space="preserve"><note-content version="0.1" xmlns:link="http://beatniksoftware.com/tomboy/link" xmlns:size="http://beatniksoftware.com/tomboy/size">things
<list><list-item dir="ltr">sheets
</list-item><list-item dir="ltr">test
</list-item><list-item dir="ltr">eval</list-item></list>
asd
</note-content>
</text><last-change-date>2023-02-19T12:20:06.551763Z</last-change-date><last-metadata-change-date>2023-02-19T12:20:06.553010Z</last-metadata-change-date><create-date>2023-02-19T10:40:01.309068Z</create-date><cursor-position>90</cursor-position><selection-bound-position>-1</selection-bound-position><width>649</width><height>282</height></note>
我想要所有文本内容,<note-content></note-content>
不带额外的换行符。这包括列表/列表项元素中的文本内容。请求的内容如下,包括格式:
things
sheets
test
eval
asd
经过多次反复尝试后,使用xmllint --xpath "//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/text() | //*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/*[local-name()='list']/*[local-name()='list-item'][@dir='ltr']/text()[normalize-space()]" a.xml
(带或不带--noblanks
) 解析 xml 会产生由额外的换行符/空行分隔的输出(后面应该有一个空行,asd
但代码块没有显示它):
things
sheets
test
eval
asd
删除 xml 文件中的新行并使用相同的 xmllint 命令输出所需的输出,而没有多余的换行符/空行,所以我不知道这是否是 Gnote 产生的非标准的东西。
我尝试查看https://stackoverflow.com/questions/11776910/xpath-expression-to-remove-whitespace/11777638,但我失败了。以下是一些观察:
- 当我尝试执行(注意
|
)时xmllint --xpath "normalize-space(//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/text()) | normalize-space(//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/*[local-name()='list']/*[local-name()='list-item'][@dir='ltr']/text())" a.xml
,我得到:
XPath 错误:类型无效
XPath 评估失败
- 即使我重新编写脚本以执行多个 xmllint 调用,我也只剩下一个删除了换行符的字符串,这很好,但是需要事先手动设置该字符串。例如,这里有 note-content 元素路径的 normalize-space 和 Translation(normalize-space, ' ', '') 变体:
xmllint --xpath "normalize-space(//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/text())" a.xml xmllint --xpath "translate(normalize-space(//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/text()), ' ', '')" a.xml
两者都在 note-content 元素中产生相同的两个项目之一,但没有换行符([1] 是 things 而 [2] 是 asd)。我可以通过将 [1] 或 [2] 附加到 text() 来在两者之间进行选择,但如果我有未定义数量的项目,则此方法不起作用。(我不知道是否有办法通过这种方式获取所有文本数组/项目)。 - 一些答案建议使用
[normalize-space() = 'desiredtext']
,如果我无法预期生成的 xml 中的文本,那么这不起作用。 - 如果我只是有
[normalize-space()]
:text()
我xmllint --noblanks --xpath "//*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/text()[normalize-space()] | //*[local-name()='note']/*[local-name()='text']/*[local-name()='note-content']/*[local-name()='list']/*[local-name()='list-item'][@dir='ltr']/text()[normalize-space()]" a.xml
留下了与我开始时相同的输出。 - 获得相同的输出
[not(.='')]
后,我尝试附加。text()
问题: 我想知道这种过多的空白行行为是由不正确的 xmllint/xpath 命令引起的,还是由于 Gnote 生成 xml 的方式以及正确的 xmllint/xpath 命令(如果有)引起的。我不想使用 xmlstarlet,因为它似乎不再维护了。这个问题不是在询问如何将其导入到删除多余换行符的命令中。
答案1
尽管您已表达了避免的偏好xmlstarlet
,但它确实会做您想要的事情:
xmlstarlet sel -t -v '//_:note-content' -n xmlfile
输出
things
sheets
test
eval
asd
使用时xmllint
我无法避免元素值文本中的空行:
xmllint --xpath '//*[local-name()="note-content"]//text()' xmlfile
输出
things
sheets
test
eval
asd
经过一段时间的思考后,xmllint
我建议你直接删除空白行。(虽然不理想,但肯定有效。)
xmllint … | grep .
输出
things
sheets
test
eval
asd