WXR 是遵循 WordPress 命名空间规范的 RSS 2.0 XML,根节点含 xmlns:wp="http://wordpress.org/export/1.2/" 等必需命名空间,结构包括 <channel>、<wp:author> 和带 wp:post_id/wp:post_parent 关联的 <item> 元素。

WordPress 的 WXR 文件就是标准 XML,但不是任意 XML 都算 WXR——它必须严格遵循 WordPress 定义的 <wp:...> 命名空间结构和内容组织规则,否则导入会失败或丢数据。
WXR 是什么 XML?看根节点和命名空间就懂了
打开导出的 wordpress-2025-12-25.xml,第一眼要确认两件事:
- 根元素是
<rss version="2.0" xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wp="http://wordpress.org/export/1.2/"> - 里面必须有
<channel>,且至少包含一个<wp:author>和若干<item>(每个<item>代表一篇帖子、页面或附件)
缺任何一个命名空间(尤其是 xmlns:wp="http://wordpress.org/export/1.2/"),WordPress 导入器会直接拒绝识别为有效 WXR。
关键结构:post 和 attachment 怎么靠 XML 关联?
WXR 把文章和它的附件(如图片、PDF)拆成独立的 <item>,靠 wp:post_id 和 wp:post_parent 绑定关系。例如:
<item> <title>我的第一篇文章</title> <wp:post_id>123</wp:post_id> <wp:post_type>post</wp:post_type> </item> <p><item> <title>封面图</title> <wp:post_id>456</wp:post_id> <wp:post_parent>123</wp:post_parent> <wp:post_type>attachment</wp:post_type> <wp:postmeta> <wp:meta_key>_wp_attached_file</wp:meta_key> <wp:meta_value>2025/12/my-cover.jpg</wp:meta_value> </wp:postmeta> </item>
这里 wp:post_parent="123" 就是告诉 WordPress:“这张图属于 ID 为 123 的文章”。如果 wp:post_parent 缺失或值不存在,导入后附件就变成“孤儿文件”,媒体库可见但文章里不显示。
Python 解析时最容易忽略的三个坑
-
xml.etree.ElementTree默认不处理命名空间,直接用find('wp:post_id')会返回None—— 必须传入namespaces={'wp': 'http://wordpress.org/export/1.2/'} - WXR 中的 HTML 内容(如
<content:encoded>)是 CDATA 包裹的,.text取出来是None,得用.text或.tail+.itertext()拼接 - 日期字段如
wp:post_date是字符串格式(2025-12-25 10:30:45),不是 ISO 8601 标准带时区的写法,用datetime.fromisoformat()会报错,得用strptime('%Y-%m-%d %H:%M:%S')
WXR 看似只是 XML,但 WordPress 导入器对结构、命名空间、字段存在性极其敏感。哪怕少一个 wp:post_date_gmt,某些插件或旧版 WP 就可能跳过整篇导入——别只盯着内容,先校验骨架。










