【问题标题】:Replace anything inside a HTML tag ID替换 HTML 标记 ID 中的任何内容
【发布时间】:2023-03-28 06:27:01
【问题描述】:

在 Stackoverflow 和 Google 上都搜索过,最接近的答案:

sed -i -e 's|<element id="lastupdate">\([0-9]\{0,\}\)</element>|<element id="lastupdate">'"$(date -d @${contents})"'</element>|g' /var/www/html/index.html

仅在标签内容为空时有效。如果已经改过,就不能再使用了。

我们的想法是更改此标记 id 内的任何内容,而不仅仅是在它为空时。

这是一个关于使用 awk 读取标签 id 内任何内容的好答案:https://stackoverflow.com/a/13148004/5623661。但它仅适用于读取(使用 awk),不适用于追加/替换(使用 sed)。

另一个想法是不仅有一种方法来替换:而且另一种方法是附加到给定标签内的任何内容中。

是否可以使用适用于 HTML 的工具而不是专门为 XML 制作的工具? 试过了:

输入:xmlstarlet ed --update '//element[@id="daipeg"]' --value 'new' index.html

输出:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Status - Floflis</title>
    <link rel="shortcut icon" href="icon.ico" type="image/x-icon"/>
    <link rel="icon" href="icon.ico" type="image/x-icon"/>
  </head>
  <body><h1>Floflis Status</h1><ul><li><p>Is DAI pegged to USD? <b><element id="daipeg">No</element></b></p></li><li><p>DAI now worth <b><element id="daiusd"/> USD</b></p></li></ul><p>Last updated in <element id="lastupdate"/> (updates every 5 minutes).</p><a href="https://floflis.github.io/" target="_blank">Main site</a> | <a href="https://floflis.github.io/blog" target="_blank">Blog</a> | <a href="https://floflis.github.io/docs" target="_blank">Documentation</a> | <a href="./api.html">DEV</a>
</body>
</html>

预期结果:将&lt;element id="daipeg"&gt;No&lt;/element&gt; 中的“否”更改为“新”,直接进入 index.html 文件。

【问题讨论】:

  • sed 是错误的工具。请Don't Parse XML/HTML With Regex.。我建议使用 XML/HTML 解析器(xmlstarlet、xmllint ...)。
  • @Cyrus:是的,但是它们以直观的方式记录得很差(html-xml-utils、HXPIPE、xmlstarlet、xmllint)。例如,在xmlstarlet:xmlstarlet ed --update '//element[@id="daipeg"]' --value 'new' index.html 中尝试了这个,它只返回 XML 标记内的 html 内容(并且没有通过 id 更改所需元素的内容。此外,这些是用于 XML,而不是 HTML。
  • 请在您的问题中添加示例输入(无描述、无图像、无链接)以及该示例输入所需的输出(无评论)。
  • 完成;已经更新了。

标签: html xml-namespaces xmlstarlet xmllint html-xml-utils


【解决方案1】:

(响应标签,我用的是1.6.1版本。)

如果您修复了命名空间问题并添加了--inplace 选项,那么您 那里(替换element 值):

test "${bettersorrythansafe}" || cp file.xhtml file.xhtml.was
xmlstarlet ed --inplace -N X='http://www.w3.org/1999/xhtml' \
    --update '//X:element[@id="daipeg"]' --value 'new' file.xhtml

或者,使用短选项和默认命名空间的快捷方式:

xmlstarlet ed -L -u '//_:element[@id="daipeg"]' -v 'new' file.xhtml

请注意,--inplace 选项在 xmlstarlet.txt 但不在user's guide 中。 有关 _ 命名空间快捷方式的更多信息,请参阅用户指南 ch. 5.

附加到值,例如:

xmlstarlet ed -L -N X='http://www.w3.org/1999/xhtml' \
    --var peg '//X:element[@id="daipeg"]' \
    --var res "$((3 * 7 * 2))" \
    -u '$peg' -x 'concat($peg," and then ",$res)' file.xhtml

【讨论】:

  • 以及如何将其标准化为除 之外的任何 (*) 其他标签?
  • 想通了。只需将element 替换为*
  • 它可以在不需要 HTML 有&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; 的情况下工作吗?
  • 如果 HTML 也是 XHTML 并且文件不包含命名空间声明,则可以:省略 -N 选项和 X: 引用。如果幸运的话,您可以使用xmlstarlet format -H -R file.html 将 HTML 转换为 XML。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 2013-09-01
  • 1970-01-01
相关资源
最近更新 更多