Domanda

I want to create a flat file from an xml using xslt with this output in the order as shown:

NM1*CC*1*Smith*John****34*999999999~
N3*100 Main Street~

From this XML:

<Claim>
 <Claimant
    lastName="Smith"
    firstName="John"
    middleName=""
    suffixName=""
    indentificationCodeQualifier="34"
    identificationCode="999999999">
    <ClaimantStreetLocation
        primary="100 Main Street"
        secondary=""/>
 </Claimant>
</Claim>

With the XSLT I created I get the output in the reversed desired order as shown below due to the nature of how XSLT works as it traverses the input tree I'm assuming:

N3*100 Main Street~
NM1*CC*1*Smith*John****34*999999999~

What do I need to change/add to get the order I am looking for to the XSLT I've written as shown: `

<xsl:template match="Claim/Claimant">
    <xsl:apply-templates />
    <xsl:text>NM1*CC*1*</xsl:text>
    <xsl:value-of select="@lastName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@firstName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@middleName" />
    <xsl:text>*</xsl:text>
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@suffixName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@indentificationCodeQualifier" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@identificationCode" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>

<xsl:template match="Claim/Claimant/ClaimantStreetLocation">
    <xsl:apply-templates />
    <xsl:text>N3*</xsl:text>
    <xsl:value-of select="@primary" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>`

Is there a way to do this without combining the two tags into one?

Any feedback would be appreciated.

I don't know if it matters, but I'm using xalan-java to process the xslt in code.

È stato utile?

Soluzione

If you want to process the parent before the children, you should move apply-templates to the end of your parent template:

<xsl:template match="Claim/Claimant">
    <xsl:text>NM1*CC*1*</xsl:text>
    <xsl:value-of select="@lastName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@firstName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@middleName" />
    <xsl:text>*</xsl:text>
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@suffixName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@indentificationCodeQualifier" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@identificationCode" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="ClaimantStreetLocation">
    <xsl:apply-templates />
    <xsl:text>N3*</xsl:text>
    <xsl:value-of select="@primary" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>`

Update: What's happening here is:

  1. The first element that is processed is Claim, but there are no templates matching it, so the default template applies, which process the templates for its children nodes.

  2. There, the first child is Claimant, and you do have a template that matches it, so it is applied.

  3. Next, that template is processed in order. But the critical point is that apply-templates omits the attributes in its default select (see What is the default select of XSLT apply-templates?), so the only matched node there is the ClaimantStreetLocation element.

  4. Given that you have a template that matches ClaimantStreetLocation, it is applied. So, if you want to process first the attributes, you should delay the apply-templates until they are selected, in your case, manually.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top