从零开发Sitemap插件遇XML声明错误,求技术支持
Let's break down why you're seeing that XML error and fix it step by step:
The Root Cause
The error means there's hidden whitespace, a Byte Order Mark (BOM), or unintended output before the <?xml declaration in your generated sitemap.xml file. XML standards require the declaration to be the very first thing in the document—any leading characters break validity.
Fix 1: Properly Initialize the $sitemap Variable
Your code starts appending to $sitemap with $sitemap .= ... without initializing it first. If PHP has any existing output (even invisible whitespace), this gets prepended to your XML. Add an explicit initialization at the top of your function:
function eg_create_sitemap() { $sitemap = ''; // Add this line to start with an empty string // Rest of your code... }
Fix 2: Eliminate Unintended Output from Your Plugin File
- Ensure your
index.phpfile starts with<?phpwithout any leading spaces, newlines, or BOM characters. Many editors add a BOM when saving UTF-8 files—switch to saving as "UTF-8 without BOM". - Remove the closing
?>tag from your PHP file if it exists. PHP doesn't require it, and any whitespace after it will be output to the file, breaking your XML structure.
Fix 3: Clean Up GMT Offset Logic (More Reliable)
Your current GMT offset code can produce invalid formats. Replace it with a simpler approach using WordPress's built-in timezone functions:
// Replace your existing $tempo logic with this $timezone = wp_timezone(); $offset = $timezone->getOffset(new DateTime()); $tempo = sprintf('%+03d:00', $offset / 3600);
Fix 4: Correct Stylesheet Filename & XML Case Sensitivity
You named your stylesheet sitemap-style.xsl but your code references sitemap.xsl—that's a typo! Also, XML is case-sensitive: valid changefreq values are lowercase (e.g., weekly, not Weekly).
Modified Working Code (All Fixes Applied)
Here's your updated function with critical fixes:
add_action("publish_post", "eg_create_sitemap"); add_action("publish_page", "eg_create_sitemap"); add_action( "save_post", "eg_create_sitemap" ); function eg_create_sitemap() { $sitemap = ''; // Initialize empty string // Fixed GMT offset calculation $timezone = wp_timezone(); $offset = $timezone->getOffset(new DateTime()); $tempo = sprintf('%+03d:00', $offset / 3600); $postsForSitemap = get_posts( array( 'numberposts' => -1, 'orderby' => 'modified', 'post_type' => array( 'post', 'page' ), 'order' => 'DESC' ) ); $sitemap .= '<?xml version="1.0" encoding="UTF-8"?>' . '<?xml-stylesheet type="text/xsl" href="' . esc_url( home_url( '/' ) ) . 'sitemap-style.xsl"?>'; // Fixed stylesheet filename $sitemap .= "\n" . '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n"; $sitemap .= "\t" . '<url>' . "\n" . "\t\t" . '<loc>' . esc_url( home_url( '/' ) ) . '</loc>' . "\n\t\t" . '<lastmod>' . date( "Y-m-d\TH:i:s", current_time( 'timestamp', 0 ) ) . $tempo . '</lastmod>' . "\n\t\t" . '<changefreq>daily</changefreq>' . "\n\t\t" . '<priority>1.0</priority>' . "\n\t" . '</url>' . "\n"; foreach( $postsForSitemap as $post ) { setup_postdata( $post); $postdate = explode( " ", $post->post_modified ); $sitemap .= "\t" . '<url>' . "\n" . "\t\t" . '<loc>' . esc_url(get_permalink( $post->ID )) . '</loc>' . "\n\t\t" . '<lastmod>' . $postdate[0] . 'T' . $postdate[1] . $tempo . '</lastmod>' . "\n\t\t" . '<changefreq>weekly</changefreq>' . "\n\t\t" . '<priority>0.5</priority>' . "\n\t" . '</url>' . "\n"; // Fixed changefreq to lowercase } $sitemap .= '</urlset>'; $fp = fopen( ABSPATH . "sitemap.xml", 'w' ); fwrite( $fp, $sitemap ); fclose( $fp ); wp_reset_postdata(); // Reset postdata to avoid breaking other queries }
Final Checks
After applying these fixes:
- Save a post or page to trigger the sitemap regeneration.
- Open
sitemap.xmlin a text editor—confirm there's nothing before the<?xmldeclaration. - Visit
https://mydomain/sitemap.xml; the XML error should be resolved, and your styled sitemap should load correctly.
内容的提问来源于stack exchange,提问作者Creative Tim

