Patricia
Patricia

Reputation: 31

xslt mapping

I have an xml file with the following values -

<InspectionChecklist>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Frame damaged</ChecklistItemDescription>
        <ChecklistItemValue>1</ChecklistItemValue>
    </InspectionChecklistItem>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Smokers Flag</ChecklistItemDescription>
        <ChecklistItemValue>1</ChecklistItemValue>
    </InspectionChecklistItem>
</InspectionChecklist>

And I want the output to look like -

<FrameDamage>Y</FrameDamage>
<SmokerFlag>Y</SmokerFlag>

So in the source xml, it is possible that I won't have any ChecklistItemDescription, or other check list item descriptions, such as -

Example 1 -

Source

<InspectionChecklist></InspectionChecklist>

I want the output to look like

<FrameDamage>N</FrameDamage>
<SmokerFlag>N</SmokerFlag>

Example 2-

Source

<InspectionChecklist>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Airbag Light</ChecklistItemDescription> 
        <ChecklistItemValue>1</ChecklistItemValue> 
    </InspectionChecklistItem>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Smokers Flag</ChecklistItemDescription> 
        <ChecklistItemValue>1</ChecklistItemValue> 
    </InspectionChecklistItem>
</InspectionChecklist>

The output should look like -

<FrameDamage>N</FrameDamage>
<SmokerFlag>Y</SmokerFlag>

I have done a few ways and can get individual ones working. But I can't get them to work for every possible case.

Any help would be appreciated.

Upvotes: 3

Views: 491

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

This transformation:

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

 <my:output>
   <frame>
    <FrameDamage>N</FrameDamage>
    <FrameDamage>Y</FrameDamage>
   </frame>
   <smoker>
    <SmokerFlag>N</SmokerFlag>
    <SmokerFlag>Y</SmokerFlag>
   </smoker>
 </my:output>

 <xsl:variable name="vFrameOutputs" select="document('')/*/my:output/frame/*"/>
 <xsl:variable name="vSmokerOutputs" select="document('')/*/my:output/smoker/*"/>
 <xsl:variable name="vDoc" select="/"/>

    <xsl:template match="/">
     <xsl:copy-of select=
       "$vFrameOutputs[($vDoc/*/*/ChecklistItemDescription='Frame damaged')+1]"/>
     <xsl:copy-of select=
       "$vSmokerOutputs[($vDoc/*/*/ChecklistItemDescription='Smokers Flag')+1]"/>
    </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<InspectionChecklist>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Frame damaged</ChecklistItemDescription>
        <ChecklistItemValue>1</ChecklistItemValue>
    </InspectionChecklistItem>
    <InspectionChecklistItem>
        <ChecklistItemDescription>Smokers2 Flag</ChecklistItemDescription>
        <ChecklistItemValue>1</ChecklistItemValue>
    </InspectionChecklistItem>
</InspectionChecklist>

produces the wanted, correct result:

<FrameDamage 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">Y</FrameDamage>
<SmokerFlag 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">N</SmokerFlag>

Do note: The namespaces in the result will not be output when the auxhiliary content in my:output is placed in its own file -- then the document() function calls need be modified to reflect the uri of the auxhiliary document.

Upvotes: 1

user357812
user357812

Reputation:

This XPath expression

/InspectionChecklist
   /InspectionChecklistItem
      /ChecklistItemDescription = 'Frame damaged' 

It results in boolean value: there is a ChecklistItemDescription with "Frame dameged" string value (true) or not (false).

We can convert this to Y or N by this expression (between others):

substring('NY', $condition + 1, 1)

I leave you the composition as a exercise to you.

Upvotes: 1

Related Questions