Reputation: 143
XSLT 1.0
Here is input XML:
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<id_brand>45</id_brand>
<brand_name><![CDATA[DIESEL]]></brand_name>
<attributes><![CDATA[Wodoodporność: 3 ATM - Średnica: 62 mm - Rodzaj: Męskie - Materiał: Stal nierdzewna - Materiał paska: Skóra - Mechanizm: Kwarcowy - Funkcje: Wielofunkcyjność - Szkiełko: Mineralne - Rodzaj produktu: Zegarek na rękę - Opakowanie: Oficjalne pudełko]]></attributes>
</product>
</products>
From this XML I need get only content from tag attributes
. Im 100% sure everything is OK with create tags from this description. Only is issues with tags <products>
and <product>
in XSLT template.
I use below XSLT template:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/products">
<product>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="normalize-space(attributes)"/>
</xsl:call-template>
</product>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="' - '"/>
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:if test="$token">
<xsl:element name="{translate(substring-before($token, ': '), ' ', '_')}">
<xsl:value-of select="substring-after($token, ': ')" />
</xsl:element>
</xsl:if>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
But something went wrong.
I try from above code to get result:
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<Wodoodporność>3 ATM</Wodoodporność>
<Średnica>62 mm</Średnica>
<Rodzaj>Męskie</Rodzaj>
<Materiał>Stal nierdzewna</Materiał>
<Materiał_paska>Skóra</Materiał_paska>
<Mechanizm>Kwarcowy</Mechanizm>
<Funkcje>Wielofunkcyjność</Funkcje>
<Szkiełko>Mineralne</Szkiełko>
<Rodzaj_produktu>Zegarek na rękę</Rodzaj_produktu>
<Opakowanie>Oficjalne pudełko</Opakowanie>
</product>
</products>
update:
@michael.hor257k you have right. But see what happens. When <products><product>...</product><product>...</product> </products>
occurs twice or more.
Everytime I get only result:
<product>
<Wodoodporność>3 ATM</Wodoodporność>
<Średnica>62 mm</Średnica>
<Rodzaj>Męskie</Rodzaj>
<Materiał>Stal nierdzewna</Materiał>
<Materiał_paska>Skóra</Materiał_paska>
<Mechanizm>Kwarcowy</Mechanizm>
<Funkcje>Wielofunkcyjność</Funkcje>
<Szkiełko>Mineralne</Szkiełko>
<Rodzaj_produktu>Zegarek na rękę</Rodzaj_produktu>
<Opakowanie>Oficjalne pudełko</Opakowanie>
</product>
This above result is from input:
Upvotes: 0
Views: 44
Reputation: 117175
But something went wrong.
That "something" is context. You are in the context of products
- but attributes
is a child of product
- therefore your instruction:
<xsl:with-param name="text" select="normalize-space(attributes)"/>
selects nothing. Change it to:
<xsl:with-param name="text" select="normalize-space(product/attributes)"/>
--- added ---
If you have multiple product
elements, then you probably want to do:
<xsl:template match="/products">
<products>
<xsl:for-each select="product">
<product>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="normalize-space(attributes)"/>
</xsl:call-template>
</product>
</xsl:for-each>
</products>
</xsl:template>
It's hard to be sure without an example showing a representative input (as code) and the expected output.
Upvotes: 1