A. M. Mérida
A. M. Mérida

Reputation: 2618

match XSLT by solr

I have an XSL which must be formed to solr. the xslt should be valid for other xml that I have created.

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:cb="http://schema.xslt.com/schema"
  version="1.0">
  <xsl:template match="/">
  <docs>
  <xsl:choose>
    <xsl:when test="cb:products">
        <xsl:apply-templates select="@*|*" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="cb:tire" />
    </xsl:otherwise>
  </xsl:choose>
  </docs>
  </xsl:template>
  <xsl:template match="cb:tire">
      <doc>
        <xsl:apply-templates select="@*|*"/>
      </doc>
  </xsl:template>
  <xsl:template match="*/*[@name]">
    <xsl:call-template name="field">
      <xsl:with-param name="name" select="concat(name(),'_',@name)"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template match="*/*[not(@name)]">
    <xsl:call-template name="field"/>
  </xsl:template>
  <xsl:template match="@*">
    <xsl:call-template name="field">
      <xsl:with-param name="value" select="."/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template match="*[parent::cb:tire]">
    <xsl:choose>
      <xsl:when test="not(text())">
        <xsl:apply-templates select="*"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="field"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template name="field">
    <xsl:param name="name" select="name()"/>
    <xsl:param name="value" select="text()"/>
    <doc>
      <field name="{$name}">
        <xsl:value-of select="$value"/>
      </field>
    </doc>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

XML:

<products>
  <tire trademark="1E" model="HP" season="1" product-type="tire"
    id="details/1E-HP" host="fe"
    hostDetailId="details/205" hostDbID="7">
    <price>51.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </tire>
  <tire trademark="FIRNE" model="FHSZ90u*" season="1" product-type="tire"
    id="details/FIRNE-FHSZ90u*" host="fe"
    hostDetailId="details/205" hostDbID="7">
    <price>72.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </tire>
</products>

the result should be. example:

<docs>
  <doc>
    <field name="hostDbID">15</field>
    ....
  </docs>
  <doc>
    <field name="hostDbID">15</field>
    ....
  </docs>
  <doc>
    <field name="hostDbID">15</field>
    ....
  </docs>
</doc>

The problem is not "macth" different attributes and elements. template is not correct?.

  <xsl:template name="field">
    <xsl:param name="name" select="name()"/>
    <xsl:param name="value" select="text()"/>
    <doc>
      <field name="{$name}">
        <xsl:value-of select="$value"/>
      </field>
    </doc>
  </xsl:template>

Thanks.

Upvotes: 0

Views: 100

Answers (1)

ABach
ABach

Reputation: 3738

There are many issues preventing me from giving an answer with certainty:

  • Your expected output XML is malformed (e.g., you don't close a <doc> element with a <docs> element).
  • I can't see why 15 would ever be a valid value of <field name="hostDbID"> (based on your example source XML).
  • Finally, putting .... inside your expected XML is never a good idea, as it forces us to guess what you want.

That said, here's my best attempt with the information provided. Let me know if I'm wrong and I will do my best to assist.

When this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/*">
    <docs>
      <xsl:apply-templates/>
    </docs>
  </xsl:template>

  <xsl:template match="tire">
    <doc>
      <xsl:apply-templates select="@*|node()"/>
    </doc>
  </xsl:template>

  <xsl:template match="tire/@*">
    <field name="{name()}">
      <xsl:value-of select="."/>
    </field>
  </xsl:template>

</xsl:stylesheet>

...is applied to the provided XML:

<products>
  <tire trademark="1E" model="HP" season="1" product-type="tire"
    id="details/1E-HP" host="fe"
    hostDetailId="details/205" hostDbID="7">
    <price>51.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </tire>
  <tire trademark="FIRNE" model="FHSZ90u*" season="1" product-type="tire"
    id="details/FIRNE-FHSZ90u*" host="fe"
    hostDetailId="details/205" hostDbID="7">
    <price>72.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </tire>
</products>

...what I assume is the correct output is produced:

<?xml version="1.0" encoding="UTF-8"?><docs>
  <doc>
    <field name="trademark">1E</field>
    <field name="model">HP</field>
    <field name="season">1</field>
    <field name="product-type">tire</field>
    <field name="id">details/1E-HP</field>
    <field name="host">fe</field>
    <field name="hostDetailId">details/205</field>
    <field name="hostDbID">7</field>
    <price>51.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </doc>
  <doc>
    <field name="trademark">FIRNE</field>
    <field name="model">FHSZ90u*</field>
    <field name="season">1</field>
    <field name="product-type">tire</field>
    <field name="id">details/FIRNE-FHSZ90u*</field>
    <field name="host">fe</field>
    <field name="hostDetailId">details/205</field>
    <field name="hostDbID">7</field>
    <price>72.95</price>
    <currency>€</currency>
    <vat>true</vat>
    <content>no description</content>
  </doc>
</docs>

Upvotes: 1

Related Questions