Reputation: 7234
I would like to merge nodes such as:
<sourcePatientInfo>PID-3|1428eab4645a4ce^^^&1.3.6.1.4.1.21367.2008.2.1&ISO</sourcePatientInfo>
<sourcePatientInfo>PID-5|WILKINS^CHARLES^^^</sourcePatientInfo>
<sourcePatientInfo>PID-8|M</sourcePatientInfo>
To a single node like this (don't worry about the node value, I have it handled):
<sourcePatientInfo>
<patientIdentifier>
</patientIdentifier>
<patientName>
</patientName>
<patientSex></patientSex>
</sourcePatientInfo>
If found a few posts: post 1 Post 2
But they are merging nodes with different names in the source xml. For now I have this:
<xsl:template match="sourcePatientInfo">
<sourcePatientInfo>
<xsl:choose>
<xsl:when test="matches(., 'PID-3')">
<patientIdentifier />
</xsl:when>
<xsl:when test="matches(., 'PID-5')">
<patientName />
</xsl:when>
<xsl:when test="matches(., 'PID-8')">
<patientSex />
</xsl:when>
</xsl:choose>
</sourcePatientInfo>
</xsl:template>
I excluded some details to avoid to much code. What I get with it is 3 separate sourcePatientInfo
which is no good.
Any help? Thank you!!!!
Upvotes: 2
Views: 556
Reputation:
This stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:l="http://localhost"
exclude-result-prefixes="l">
<l:n id="PID-3">patientIdentifier</l:n>
<l:n id="PID-5">patientName</l:n>
<l:n id="PID-8">patientSex</l:n>
<xsl:variable name="vNames" select="document('')/*/l:n"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="sourcePatientInfo"/>
<xsl:template match="sourcePatientInfo[1]">
<xsl:copy>
<xsl:apply-templates
select=".|following-sibling::sourcePatientInfo"
mode="merge"/>
</xsl:copy>
</xsl:template>
<xsl:template match="sourcePatientInfo" mode="merge">
<xsl:apply-templates
select="$vNames[@id=substring-before(current(),'|')]">
<xsl:with-param name="pCurrent" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="l:n">
<xsl:param name="pCurrent" select="/.."/>
<xsl:element name="{.}">
<xsl:value-of select="substring-after($pCurrent,'|')"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
With this input:
<item>
<sourcePatientInfo>PID-3|1428eab4645a4ce^^^&1.3.6.1.4.1.21367.2008.2.1&ISO</sourcePatientInfo>
<sourcePatientInfo>PID-5|WILKINS^CHARLES^^^</sourcePatientInfo>
<sourcePatientInfo>PID-8|M</sourcePatientInfo>
</item>
Output:
<item>
<sourcePatientInfo>
<patientIdentifier>1428eab4645a4ce^^^&1.3.6.1.4.1.21367.2008.2.1&ISO</patientIdentifier>
<patientName>WILKINS^CHARLES^^^</patientName>
<patientSex>M</patientSex>
</sourcePatientInfo>
</item>
EDIT: Applying templates to inline map's nodes for "complex" further processing.
Upvotes: 6