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:44:36 -0000
Well I have solved it by explicitly testing that the element name generated
is not zero-length

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

If anybody can see how I was getting zero-length element names in the first
place I would be eager to know because that test appears to be redundant.

The only possible explanation is that there is a mismatch between the
number of field elements and the number of xs:elements they are being
matched to so maybe I should look further upstream.

Thank you again dimitre

On Mon, May 30, 2016 at 5:31 AM, Ihe Onwuka ihe.onwuka@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> Ughhh. Scratch the last post as it is full of mistakes. Here is the
> correction.
>
> 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="pos" 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>
>
>  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 (assume the apply-templates is
> handled by an identity template)
>
>   <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.
>
>
> On Mon, May 30, 2016 at 5:24 AM, Ihe Onwuka ihe.onwuka@xxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>>
>>
>> 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.
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://-list/1005724> (by email)
>>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <-list/1005724> (by
> email <>)

Current Thread