Reputation: 31
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
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
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