私も同じ現象に行き当たりました。WordPress2.8 でも問題は修正されていないようです。
maxline さんの修正をヒントに下記のように /wp-admin/import/wordpress.php の該当箇所を from から to に変更しました。
/*
* line 403-404:
*/
// from:
preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
$categories = $categories[1];
// to:
preg_match_all('|<category domain="category" nicename="([0-9a-z%\-_]*?)">(.*?)</category>|is', $post, $categories);
$nicenames = $categories[1];
$categories = $categories[2];
/*
* Line 462-482
*/
// from:
if (count($categories) > 0) {
$post_cats = array();
foreach ($categories as $category) {
if ( '' == $category )
continue;
$slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
$cat = get_term_by('slug', $slug, 'category');
$cat_ID = 0;
if ( ! empty($cat) )
$cat_ID = $cat->term_id;
if ($cat_ID == 0) {
$category = $wpdb->escape($category);
$cat_ID = wp_insert_category(array('cat_name' => $category));
if ( is_wp_error($cat_ID) )
continue;
}
$post_cats[] = $cat_ID;
}
wp_set_post_categories($post_id, $post_cats);
}
// to:
if ($c = count($categories) > 0) {
$post_cats = array();
for ($i = 0; $i < $c; $i++ ) {
if ( '' == $categories[$i] || '' == $nicenames[$i] )
continue;
$cat = get_term_by('slug', $nicenames[$i], 'category');
if ( empty($cat) || $cat->name != $categories[$i] ) {
$slug = sanitize_term_field('slug', $categories[$i], 0, 'category', 'db');
$cat = get_term_by('slug', $slug, 'category');
}
$cat_ID = 0;
if ( ! empty($cat) )
$cat_ID = $cat->term_id;
if ($cat_ID == 0) {
$category = $wpdb->escape($categories[$i]);
$cat_ID = wp_insert_category(array('cat_name' => $category));
if ( is_wp_error($cat_ID) )
continue;
}
$post_cats[] = $cat_ID;
}
wp_set_post_categories($post_id, $post_cats);
}
これで xml ファイル (WXR) の方を書き換えなくても正常にインポートできるはずです。互換性については、 WP_Import::process_post() の該当箇所を各バージョンで比較した感じ、WP2.6.5 以上では少なくとも動作するのではないかと思います。
懸念としては nicename 属性を持つ category 要素がどのバージョンの WordPress インポート用 RSS に追加されたかで、WXR ファイルの構造によっては下位互換性が取れないこともあるかもしれません。
<category><![CDATA[未分類]]></category>
<category domain="category" nicename="uncategorized"><![CDATA[未分類]]></category>
それから、カテゴリーの正確さを検証する際のポリシーがよく分からないこと。カテゴリー名の重複を許可する一方、スラッグは単一、しかしながらインポート時にはカテゴリー名を基準にする、というインポーターの挙動に混乱します。
スラッグ名とカテゴリー名が既存のものと一致する場合にのみ、そのカテゴリーの投稿としてインポートする、というのでいいと最初は思っていたんですが、投稿のインポートの前に走るカテゴリーのインポート時に、カテゴリー名が異なるがスラッグは同じというカテゴリーがインポート元のブログに既に存在し、インポートされるカテゴリーのスラッグが WXR ファイルに記述されているのではない、ユニークな別のものに変更されていた場合には、新たなスラッグを追跡する必要があるのですが、適切な方法が分かりません。
そこでとりあえずそのような場合も結局、新規に同名のカテゴリーを追加するという従来の処理に任せてみるのですが、カテゴリーの正確さを検証するポリシーがあるのであれば、それに準拠しないとコミットできないので、、、という。
長々と書きましたが、添削を含め、どなたか情報をお持ちでしたらご教示ください。
> maxline さん
プラグイン化については、 WP_Import を継承したクラスで process_post() メソッドを定義し直して、 register_importer() すれば出来そうですね。