Add/remove xml 来自带有 bash 的 svg 文件的字段
Add/remove xml field from svg file with bash
我有一组 svg 图像,我想用 bash 脚本修改它们。特别是,我想通过保留其他路径从图像中删除特定路径。这是一个工作示例:
<path
id="rect5505"
d="M 118.34375,20 C ... z"
style="fill:#4d8ecb;stroke:none;fill-opacity:1" />
<path
style="fill:#000000;fill-opacity:0.23529412;stroke:none;display:inline"
d="m ... z"
id="path17954"
sodipodi:nodetypes="ssccccccccccccssccccccs" />
在这种情况下,有两个 path
元素,但我只想删除具有 fill:#000000;fill-opacity:0.23529412
的那个。我知道我可以使用 sed
来识别具有这些字段的行,但是如何删除整个 path
字段?
我想强调这个问题不是 Add/remove xml tags using a bash script 的重复,因为在那种情况下只有一个字段类型。通过使用类似
sed -i '/<path/,/<\/>/d' image.svg
我会删除文件中的每个路径,不是吗?
用 sed 编辑 XML 不是一个好主意。我的建议是使用 xmlstarlet
:
xmlstarlet ed -d '//path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]' filename.xml
在哪里
xmlstarlet ed -d xpath filename.xml
从 filename.xml
中删除那些与给定 XPath 表达式匹配的元素,并且
//path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]
是一个 XPath 表达式,匹配所有具有 style
属性的 path
节点,该属性同时包含 fill:#000000
和 fill-opacity:0.23529412
。
附录: 由于 contains()
进行简单的字符串比较,上面使用的 XPath 表达式在某些极端情况下可能会产生误报。例如,如果 style
属性包含字符串 foo-fill:#000000
,则 contains(@style, "fill:#000000")
将为真。解决这个特定问题的一个简单但有点笨拙的方法是使用
xmlstarlet ed -d '//path[contains(concat(";", @style, ";"), ";fill:#000000;") and contains(concat(";", @style, ";"), ";fill-opacity:0.23529412;")]' filename.xml
...尽管这仍然存在空格问题。我想一个完美的解决方案必须解析 CSS 以及 XML,这将需要更多的工作(可能还有 Perl 左右)。
附录 2: 看来我们有 namespace SNAFU。要解决这个问题,请使用
xmlstarlet ed -N svg='http://www.w3.org/2000/svg' -d '//svg:path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]' accessibility.svg
即:
xmlstarlet ed -N svg='http://www.w3.org/2000/svg' -d xpath filename
将 xpath
修改为使用 svg:path
而不是 path
。这是必要的,因为有一个属性
xmlns="http://www.w3.org/2000/svg"
在输入文件的 svg
标签中,XPath 要求处理它。
我有一组 svg 图像,我想用 bash 脚本修改它们。特别是,我想通过保留其他路径从图像中删除特定路径。这是一个工作示例:
<path
id="rect5505"
d="M 118.34375,20 C ... z"
style="fill:#4d8ecb;stroke:none;fill-opacity:1" />
<path
style="fill:#000000;fill-opacity:0.23529412;stroke:none;display:inline"
d="m ... z"
id="path17954"
sodipodi:nodetypes="ssccccccccccccssccccccs" />
在这种情况下,有两个 path
元素,但我只想删除具有 fill:#000000;fill-opacity:0.23529412
的那个。我知道我可以使用 sed
来识别具有这些字段的行,但是如何删除整个 path
字段?
我想强调这个问题不是 Add/remove xml tags using a bash script 的重复,因为在那种情况下只有一个字段类型。通过使用类似
sed -i '/<path/,/<\/>/d' image.svg
我会删除文件中的每个路径,不是吗?
用 sed 编辑 XML 不是一个好主意。我的建议是使用 xmlstarlet
:
xmlstarlet ed -d '//path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]' filename.xml
在哪里
xmlstarlet ed -d xpath filename.xml
从 filename.xml
中删除那些与给定 XPath 表达式匹配的元素,并且
//path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]
是一个 XPath 表达式,匹配所有具有 style
属性的 path
节点,该属性同时包含 fill:#000000
和 fill-opacity:0.23529412
。
附录: 由于 contains()
进行简单的字符串比较,上面使用的 XPath 表达式在某些极端情况下可能会产生误报。例如,如果 style
属性包含字符串 foo-fill:#000000
,则 contains(@style, "fill:#000000")
将为真。解决这个特定问题的一个简单但有点笨拙的方法是使用
xmlstarlet ed -d '//path[contains(concat(";", @style, ";"), ";fill:#000000;") and contains(concat(";", @style, ";"), ";fill-opacity:0.23529412;")]' filename.xml
...尽管这仍然存在空格问题。我想一个完美的解决方案必须解析 CSS 以及 XML,这将需要更多的工作(可能还有 Perl 左右)。
附录 2: 看来我们有 namespace SNAFU。要解决这个问题,请使用
xmlstarlet ed -N svg='http://www.w3.org/2000/svg' -d '//svg:path[contains(@style, "fill:#000000") and contains(@style, "fill-opacity:0.23529412")]' accessibility.svg
即:
xmlstarlet ed -N svg='http://www.w3.org/2000/svg' -d xpath filename
将 xpath
修改为使用 svg:path
而不是 path
。这是必要的,因为有一个属性
xmlns="http://www.w3.org/2000/svg"
在输入文件的 svg
标签中,XPath 要求处理它。