使用xsl:for-each处理WordPress导出XML的category domain分组问题
WordPress XML转分类表的XSLT问题解决
问题描述
将WordPress导出的XML文件转换为数据库可用的分类表时,使用<xsl:for-each>遍历分类节点后,仅生成一行数据,无法得到每个分类对应的多行记录。
示例XML
<rss xmlns:wp="http://wordpress.org/export/1.2/"> <channel> <title>TEST</title> <description>test</description> <pubDate>Thu, 18 Jan 2024 09:32:27 +0000</pubDate> <language>es</language> <wp:wxr_version>1.2</wp:wxr_version> <wp:base_site_url>some url</wp:base_site_url> <wp:base_blog_url>some url</wp:base_blog_url> <item> <title><![CDATA[Minio Plomo Electrolítico]]></title> <link>url</link> <wp:post_id>80</wp:post_id> <wp:post_name><![CDATA[minio-plomo-electrolitico-750-ml]]></wp:post_name> <category domain="test_iconos" nicename="base-solvente"><![CDATA[2-Base Solvente]]></category> <category domain="test_iconos" nicename="rendimiento-de-5-a-6-m2-kg"><![CDATA[35-Rendimiento de 5 a 6 m2/ Kg]]></category> <category domain="test_iconos" nicename="brocha-rodillo-pistola"><![CDATA[41-Brocha-Rodillo-Pistola]]></category> <category domain="test_iconos" nicename="exterior-interior"><![CDATA[45-Exterior-Interior]]></category> <category domain="test_iconos" nicename="lavabilidad-nivel-maximo"><![CDATA[64-Lavabilidad Nivel Máximo]]></category> <category domain="test_familias" nicename="esmaltes-imprimaciones-y-selladoras"><![CDATA[Esmaltes, Imprimaciones y Selladoras]]></category> <wp:postmeta> <wp:meta_key><![CDATA[_edit_last]]></wp:meta_key> <wp:meta_value><![CDATA[13]]></wp:meta_value> </wp:postmeta> <wp:postmeta> <wp:meta_key><![CDATA[test_referencia]]></wp:meta_key> <wp:meta_value><![CDATA[33200031]]></wp:meta_value> </wp:postmeta> </item> </channel> </rss>
期望输出
<div class="s-table-container"> <table class="s-table"> <thead> <tr> <th>Post_Id</th> <th>Iconos</th> </tr> </thead> <tbody> <tr> <td>80</td> <td>2-Base Solvente</td> </tr> <tr> <td>80</td> <td>35-Rendimiento de 5 a 6 m2/ Kg</td> </tr> <tr> <td>80</td> <td>41-Brocha-Rodillo-Pistola</td> </tr> <tr> <td>80</td> <td>45-Exterior-Interior</td> </tr> <tr> <td>80</td> <td>64-Lavabilidad Nivel Máximo</td> </tr> </tbody> </table> </div>
错误的XSLT代码
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:wp="http://wordpress.org/export/1.2/"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <tbIconos> <xsl:for-each select="/rss/channel/item/category[@domain = 'test_iconos']"> <!--<xsl:for-each select="key ('iconos',../category[@domain])"> --> <Post_id> <xsl:value-of select="/rss/channel/item/wp:post_id"/> </Post_id> <Iconos> <xsl:value-of select="/rss/channel/item/category"/> </Iconos> </xsl:for-each> </tbIconos> </xsl:template> </xsl:stylesheet>
问题原因
原代码使用绝对路径(/rss/channel/item/wp:post_id、/rss/channel/item/category)获取节点值,每次循环都会选中整个XML中第一个匹配的节点,导致所有循环输出相同的内容,且仅取第一个分类的文本。
修正后的XSLT代码
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:wp="http://wordpress.org/export/1.2/"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <div class="s-table-container"> <table class="s-table"> <thead> <tr> <th>Post_Id</th> <th>Iconos</th> </tr> </thead> <tbody> <!-- 遍历每个文章节点 --> <xsl:for-each select="/rss/channel/item"> <!-- 存储当前文章的ID,避免重复查找 --> <xsl:variable name="currentPostId" select="wp:post_id"/> <!-- 遍历当前文章下所有domain为test_iconos的分类 --> <xsl:for-each select="category[@domain = 'test_iconos']"> <tr> <td> <xsl:value-of select="$currentPostId"/> </td> <td> <xsl:value-of select="."/> </td> </tr> </xsl:for-each> </xsl:for-each> </tbody> </table> </div> </xsl:template> </xsl:stylesheet>
修正说明
- 将输出方法改为
html,匹配期望的HTML表格格式 - 先遍历每个
<item>节点,再在内部遍历目标分类,确保每个分类对应所属的文章ID - 使用变量
currentPostId存储当前文章ID,提升代码可读性与执行效率 - 用相对路径
.获取当前遍历到的分类文本内容,保证循环输出正确的分类值
内容的提问来源于stack exchange,提问作者Jose Antonio García
相关产品推荐
相关产品推荐

