I need to rearrange the source XML file with my transformation to obtain:
- A new elements order. Look the difference between source and desired output:
<gmd:role>
should appear AFTER<contactInfo>
and elements inside<CI_Contact>
have to appear in different order too. - Add elements that are not present in the source as empty elements in the output otherwise copy the element as-is (look at the
<address>
element)
Source file:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="c:\ISO19139_rve.xsl"?>
<MD_Metadata xmlns="http://www.isotc211.org/schemas/2005/gmd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/schemas/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.isotc211.org/schemas/2005/gmd/gmd.xsd">
<CI_ResponsibleParty>
<organizationName>
<gco:CharacterString>Organisation Name</gco:CharacterString>
</organizationName>
<role>
<CI_RoleCode codeList="./resource/codeList.xml#CI_RoleCode" codeListValue="Proprietario">Proprietario</CI_RoleCode>
</role>
<contactInfo>
<CI_Contact>
<onlineResource>
<CI_OnlineResource>
<linkage>
<URL>http://www.mydomain.it</URL>
</linkage>
</CI_OnlineResource>
</onlineResource>
<phone>
<CI_Telephone>
<voice>
<gco:CharacterString>+39 123 456789</gco:CharacterString>
</voice>
</CI_Telephone>
</phone>
</CI_Contact>
</contactInfo>
</CI_ResponsibleParty>
</MD_Metadata>
Desired result:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="c:\ISO19139_rve.xsl"?>
<MD_Metadata xmlns="http://www.isotc211.org/schemas/2005/gmd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gco="http://www.isotc211.org/schemas/2005/gco"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="http://www.isotc211.org/schemas/2005/gmd/gmd.xsd">
<gmd:CI_ResponsibleParty>
<gmd:organisationName>
<gco:CharacterString>Organisation Name</gco:CharacterString>
</gmd:organisationName>
<gmd:contactInfo>
<gmd:CI_Contact>
<gmd:phone>
<gmd:CI_Telephone>
<gmd:voice>
<gco:CharacterString>+39 123 456789</gco:CharacterString>
</gmd:voice>
</gmd:CI_Telephone>
</gmd:phone>
<gmd:address>
<gmd:CI_Address>
<gmd:electronicMailAddress>
<gco:CharacterString/>
</gmd:electronicMailAddress>
</gmd:CI_Address>
</gmd:address>
<gmd:onlineResource>
<gmd:CI_OnlineResource>
<gmd:linkage>
<gmd:URL>http://www.mydomain.it</gmd:URL>
</gmd:linkage>
</gmd:CI_OnlineResource>
</gmd:onlineResource>
</gmd:CI_Contact>
</gmd:contactInfo>
<gmd:role>
<gmd:CI_RoleCode codeList="./resource/codeList.xml#CI_RoleCode" codeListValue="owner">Proprietario</gmd:CI_RoleCode>
</gmd:role>
</gmd:CI_ResponsibleParty>
</MD_Metadata>
My transformation:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:gco="http://www.isotc211.org/schemas/2005/gco"
xmlns:gmd="http://www.isotc211.org/schemas/2005/gmd"
xmlns="http://www.isotc211.org/schemas/2005/gmd"
>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" encoding="UTF-8"/>
<!-- identity template -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="gmd:CI_ResponsibleParty" exclude-result-prefixes="#all">
<xsl:copy>
<!--<xsl:copy-of select="@*" />-->
<xsl:copy-of select="gmd:organizationName" />
<xsl:apply-templates select="gmd:contactInfo" />
<xsl:copy-of select="gmd:role" />
<!--<xsl:apply-templates select="node()" />-->
</xsl:copy>
</xsl:template>
<!--<xsl:template match="gmd:contactInfo" />-->
<xsl:template match="gmd:contactInfo" exclude-result-prefixes="#all">
<xsl:copy>
<xsl:copy-of select="gmd:phone" />
<xsl:apply-templates select="gmd:address" />
<xsl:if test="not(gmd:address)">
<address>
<CI_Address>
<electronicMailAddress>
<gco:CharacterString/>
</electronicMailAddress>
</CI_Address>
</address>
</xsl:if>
<xsl:copy-of select="gmd:onlineResource" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I think you want to use
<xsl:template match="gmd:CI_contact">
, not<xsl:template match="gmd:contactInfo">
As a good practice: In stylesheets that are based on the identity template, prefer
<xsl:apply-templates>
over<xsl:copy>
.The end effect will be the same (the input will be copied) but this way you keep it easy to append another template that handles a special case while not having to touch the existing templates.
Hypothetically: Say you want to drop all
@foo
attributes everywhere. Because the above uses<xsl:apply-templates select="@*">
, it's a matter of appendingHowever if you use
<xsl:copy-of select="@*" />
you'd have to change this line and probably a dozen other places where@foo
would be copied.