修改文件 DOM 中 node 的 attribute 并保存修改回原文件

我有个需求,想要修改 svg 中引用的图片 image 的 href 的值,并保存回原 svg 文件。

比如原来的 svg 文本是如下:


<svg width="560" height="420" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><rect x="0" y="0" width="560" height="420" id="edraw-background" stroke="none" fill="#fff" /><g id="edraw-body"><image xlink:href="/Users/c/Library/Mobile Documents/iCloud~com~appsonthemove~beorg/Documents/braindump/notes/static/STM32F10xxx/1.png" height="512" width="447" y="-40" x="40" /></g></svg>

在 svg tag 中的 image tag 的 xlink:href 属性的值为 /Users/c/Library/Mobile Documents/iCloud~com~appsonthemove~beorg/Documents/braindump/notes/static/STM32F10xxx/1.png 这么一串字符,我希望将其修改为其他值,如 any.png,并保存回原文件。 而 svg 文本的其他部分不变。

我自己写的一个:

(defun modify-svg-xml (full-file-path)
      (let (new-file-name
            image-href-attr)
       (with-temp-buffer
        (insert-file-contents full-file-path)
        (cl-loop for child in (dom-by-tag (libxml-parse-html-region (point-min) (point-max)) 'image)
                 do (progn
                      (setq image-href-attr (dom-attr child 'xlink:href))
                      (setq new-file-name (md5 (format "%s" (random))))
                      (save-excursion
                        (goto-char (point-min))
                        (while (re-search-forward
                                image-href-attr
                                (point-max)
                                t)
                          (replace-match (file-name-with-extension new-file-name (file-name-extension image-href-attr)) t nil nil nil)))
                      ))
        (write-file full-file-path nil)
        (buffer-string))))

使用 re-search-forward 正则查找需要被替换的字符串,再替换成新的。可是当 image tag 的 xlink:href 包含中文时,正则查找往往失灵。

不知道有没有其他的方案?

字符集编码问题,正则里的中文需要转成 unibyte

2 个赞

谢谢提示,已解决。