先把当时的情况摆出来。筛选页的地址带了几十个参数,长度超过两千字符。sitemap 校验工具提示格式错误,用 GSC 提交后整份文件显示已读取但条目数少了几百条。

这类报错背后常见的原因有几处,逐个排除就行。单个 loc 的长度上限是 2048 字符,超长地址不被接受。还有一种是XML 里的 & 没有转义成 &,解析在第一个参数处就断了。

不容易想到的是,超长地址多为筛选组合页,本身也不该进 sitemap。还有一种情况,插件把地址直接拼进模板,没有做 URL 编码。

量一下最长地址的字符数

curl -s https://www.example.com/sitemap-1.xml | grep -o '<loc>[^<]*' | awk '{print length, $0}' | sort -rn | head -3

过滤掉参数过多的地址

add_filter('wp_sitemaps_posts_query_args', function($a){ $a['meta_query'][] = ['key'=>'skip_sitemap','compare'=>'NOT EXISTS']; return $a; });

转义 XML 里的特殊字符

perl -pi -e 's/&/&amp;/g' sitemap-1.xml

等前面都确认过,再用校验工具复查条目数

xmllint --noout sitemap-1.xml

别只看报错消失,验证要多做一步。校验工具不再报错,sitemap 的条目数与数据库里符合条件的 URL 数一致,GSC 显示读取到的地址数同步增加。

补一句。超长地址基本都来自筛选组合,与其想办法塞进 sitemap,不如直接给这类页面加 canonical 或屏蔽,省得两边都别扭。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189