如何使用 xmllint 停止以空行分隔的输出

如何使用 xmllint 停止以空行分隔的输出

我有从 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,但我失败了。以下是一些观察:

  1. 当我尝试执行(注意|)时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 评估失败

  1. 即使我重新编写脚本以执行多个 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() 来在两者之间进行选择,但如果我有未定义数量的项目,则此方法不起作用。(我不知道是否有办法通过这种方式获取所有文本数组/项目)。
  2. 一些答案建议使用[normalize-space() = 'desiredtext'],如果我无法预期生成的 xml 中的文本,那么这不起作用。
  3. 如果我只是有[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 留下了与我开始时相同的输出。
  4. 获得相同的输出[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

相关内容