Re: [xsl] Really want a zipper

Subject: Re: [xsl] Really want a zipper
From: "Ihe Onwuka ihe.onwuka@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 30 May 2016 09:24:39 -0000
On Sun, May 29, 2016 at 11:24 PM, Dimitre Novatchev dnovatchev@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> If my guess about the wanted result is correct, then this transformation:
>
> <xsl:stylesheet version="2.0"  xmlns:xsl="
> http://www.w3.org/1999/XSL/Transform";
>  xmlns:xs="http://www.w3.org/2001/XMLSchema";>
>  <xsl:output omit-xml-declaration="yes" indent="yes"/>
>  <xsl:strip-space elements="*"/>
>
>  <xsl:variable name="vElemNames" select=
>  "doc('midas.xsd')/*/*/*/xs:element/@name/string()"/>
>
>   <xsl:template match="node()|@*">
>    <xsl:copy>
>      <xsl:apply-templates select="node()|@*"/>
>    </xsl:copy>
>  </xsl:template>
>
>  <xsl:template match="field">
>    <xsl:variable name="vPos" select="position()"/>
>
>    <xsl:element name="{$vElemNames[$vPos]}">
>      <xsl:apply-templates select="node()|@*"/>
>    </xsl:element>
>   </xsl:template>
> </xsl:stylesheet>
>
> when applied on the provided XML document:
>
> <midas>
>  <issuerSummary>
>   <field id="1">01</field>
>   <field id="2">54631</field>
>   <field id="3">VA</field>
>   <field id="4">11512</field>
>   <field id="5">04222016</field>
>  </issuerSummary>
> </midas>
>
> and referencing the provided XSD file (midas.xsd):
>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
>  xmlns="urn:midas" targetNamespace="urn:midas"
>  elementFormDefault="qualified">
>  <xs:complexType name="IssuerSummaryType">
>   <xs:sequence>
>    <xs:element name="recordCode">
>     <xs:simpleType>
>      <xs:restriction base="Text2Type">
>       <xs:enumeration value="01"/>
>      </xs:restriction>
>     </xs:simpleType>
>    </xs:element>
>    <xs:element name="tradingPartner" type="TradingPartnerType"/>
>    <xs:element name="issuerStateCode" type="Text2Type"/>
>    <xs:element name="HIOSid" type="HIOSIDType"/>
>    <xs:element name="issuerExtractDate" type="xs:date"/>
>   </xs:sequence>
>  </xs:complexType>
> </xs:schema>
>
> produces (what I guess is) the wanted, correct result:
>
> <midas>
>    <issuerSummary>
>       <recordCode id="1">01</recordCode>
>       <tradingPartner id="2">54631</tradingPartner>
>       <issuerStateCode id="3">VA</issuerStateCode>
>       <HIOSid id="4">11512</HIOSid>
>       <issuerExtractDate id="5">04222016</issuerExtractDate>
>    </issuerSummary>
> </midas>
>
>
Yes that is the correct result - my apologies for not making that explicit
and thank you for your answer and the problem you posted works as you
designed it on my setup.

However I cannot do a straight transcription because the full problem is
more complex than posted. The schema actually has several complexTypes so
putting all the xs:element/@name in a variable will not work. Let me pose
this a different way by focusing on the field template below.

  <xsl:template match="field">
    <xsl:param name="recordType"/>
    <xsl:variable name="vPos" select="position()"/>
    <field>
         <xsl:value-of
 select="$recordType/xs:element[$pos]/@name/string()"/>
     </field>
  </xsl:template>

Suppose I have the above where the param recordType contains the parent
xs:sequence of the correct set of xs:elements. So in this instance
$recordType contains

<xs:sequence>
   <xs:element name="recordCode">
    <xs:simpleType>
     <xs:restriction base="Text2Type">
      <xs:enumeration value="01"/>
     </xs:restriction>
    </xs:simpleType>
   </xs:element>
   <xs:element name="tradingPartner" type="TradingPartnerType"/>
   <xs:element name="issuerStateCode" type="Text2Type"/>
   <xs:element name="HIOSid" type="HIOSIDType"/>
   <xs:element name="issuerExtractDate" type="xs:date"/>
  </xs:sequence>

Above I have hardcoded the template to give me the 5th xs:element and
template obliges by naming all the elements issuerExtractDate and I get.

<midas>
   <issuerSummary>
      <field>recordCode</field>
      <field>tradingPartner</field>
      <field>issuerStateCode</field>
      <field>HIOSid</field>
      <field>issuerExtractDate</field>
   </issuerSummary>
</midas>

So the correct fields are being picked up and everything works when the
field names are treated as data.

So all I have to do now is to make the element names the content of the
field elements.

But if I move the exact same expression from the value-of into the AVT of
the name attribute of xs:element like so

  <xsl:template match="field">
    <xsl:param name="recordType"/>
    <xsl:variable name="pos" select="position()"/>
    <xsl:element name="{$recordType/xs:element[$pos]/@name/string()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

 I get XTDE0820: Supplied element name is a zero-length string.

So what I really need to know is why that happens.

Current Thread