Search code examples
xmldatabasewordpressxsltforeach

Problem using xsl:for-each in a Worpress export XML archive to group category domain


I need to import an XML generated by Wordpress to a database. For this I am using an XSLT file but I have problems creating the category table. I have tried using xsl:for-each but it didn't work. The original XML (example) would be this:

<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>

The result i need a it´s a table like this :

Post_Id Iconos
80 2-Base Solvente
80 35-Rendimiento de 5 a 6 m2/ Kg
80 41-Brocha-Rodillo-Pistola
80 45-Exterior-Interior
80 64-Lavabilidad Nivel Máximo

I have try writing this xsl :

<?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>

But i only get this result:

Post_Id Iconos
80 2-Base Solvente

Solution

  • I can only guess you want to do:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wp="http://wordpress.org/export/1.2/" exclude-result-prefixes="wp">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/rss">
        <tbIconos>
            <xsl:for-each select="channel/item"> 
                <xsl:variable name="post-id" select="wp:post_id" />
                <xsl:for-each select="category[@domain='test_iconos']"> 
                    <Post_id>
                        <xsl:value-of select="$post-id"/>
                    </Post_id>
                    <Iconos>
                        <xsl:value-of select="."/>
                    </Iconos>
                </xsl:for-each>
            </xsl:for-each>
        </tbIconos>
    </xsl:template>
    
    </xsl:stylesheet>
    

    But it seems to me there should be a wrapping element for each record (row of your table).