Reputation: 79
How can i output the value of NUMBER
for every GRP/ADD/CONTACT
where QUALIFIER = EM?
Correct output should be: [email protected]
. Please find my XML and XSLT attached:
XML:
<?xml version="1.0"?>
<TEST>
<CNT>
<GRP>
<ADD>
<QUALIFIER>DP</QUALIFIER>
<PARTY_NAME_1>Vorname Nachname</PARTY_NAME_1>
<STREET_1>Strasse 1</STREET_1>
<CITY>Ort</CITY>
<POSTAL_CODE>12345</POSTAL_CODE>
<COUNTRY_CODE>DE</COUNTRY_CODE>
<CONTACT>
<QUALIFIER>TE</QUALIFIER>
<NUMBER>4657</NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER>EM</QUALIFIER>
<NUMBER>[email protected]</NUMBER>
</CONTACT>
</ADD>
<ADD>
<QUALIFIER>ST</QUALIFIER>
<PARTY_NAME_1>Vorname Nachname</PARTY_NAME_1>
<STREET_1>Strasse 1</STREET_1>
<CITY>Ort</CITY>
<POSTAL_CODE>12345</POSTAL_CODE>
<COUNTRY_CODE>DE</COUNTRY_CODE>
<CONTACT>
<QUALIFIER>TE</QUALIFIER>
<NUMBER>12345</NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER>EM</QUALIFIER>
<NUMBER>[email protected]</NUMBER>
</CONTACT>
</ADD>
</GRP>
</CNT>
</TEST>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GRP">
<xsl:copy>
<xsl:for-each select ="./ADD/CONTACT[QUALIFIER='ST']">
<xsl:if test="./QUALIFIER='EM'">
<CONTACT_EMAIL>
<xsl:value-of select="NUMBER"/>
</CONTACT_EMAIL>
</xsl:if>
</xsl:for-each>
<!--copy all other nodes -->
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- delete empty nodes -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>
<!-- delete empty nodes -->
</xsl:stylesheet>
I also tried this:
<xsl:for-each select ="./ADD/CONTACT">
instead of <xsl:for-each select ="./ADD/CONTACT[QUALIFIER='ST']">
, but there i get all data of the value "number" (from qualifier DP and ST) but i need just from qualifier ST.
Upvotes: 1
Views: 83
Reputation: 117043
If that's the result you want, you could do simply:
<xsl:template match="GRP">
<xsl:copy>
<xsl:for-each select ="ADD[QUALIFIER='ST']/CONTACT[QUALIFIER='EM']">
<CONTACT_EMAIL>
<xsl:value-of select="NUMBER"/>
</CONTACT_EMAIL>
</xsl:for-each>
<!--copy all other nodes -->
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
Upvotes: 1
Reputation: 79
<xsl:template match="GRP">
<xsl:copy>
<xsl:for-each select ="./ADD[QUALIFIER='ST']">
<xsl:if test="./CONTACT/QUALIFIER='EM'">
<CONTACT_EMAIL>
<xsl:value-of select="CONTACT[QUALIFIER='EM']/NUMBER"/>
</CONTACT_EMAIL>
</xsl:if>
</xsl:for-each>
<!--copy all other nodes -->
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
Result:
<TEST>
<CNT>
<GRP>
<CONTACT_EMAIL>[email protected]</CONTACT_EMAIL>
<ADD>
<QUALIFIER>DP</QUALIFIER>
<PARTY_NAME_1>Vorname Nachname</PARTY_NAME_1>
<STREET_1>Strasse 1</STREET_1>
<CITY>Ort</CITY>
<POSTAL_CODE>12345</POSTAL_CODE>
<COUNTRY_CODE>DE</COUNTRY_CODE>
<CONTACT>
<QUALIFIER>TE</QUALIFIER>
<NUMBER>4657</NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER>EM</QUALIFIER>
<NUMBER>[email protected]</NUMBER>
</CONTACT>
</ADD>
<ADD>
<QUALIFIER>ST</QUALIFIER>
<PARTY_NAME_1>Vorname Nachname</PARTY_NAME_1>
<STREET_1>Strasse 1</STREET_1>
<CITY>Ort</CITY>
<POSTAL_CODE>12345</POSTAL_CODE>
<COUNTRY_CODE>DE</COUNTRY_CODE>
<CONTACT>
<QUALIFIER>TE</QUALIFIER>
<NUMBER>12345</NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER>EM</QUALIFIER>
<NUMBER>[email protected]</NUMBER>
</CONTACT>
</ADD>
</GRP>
</CNT>
</TEST>
Upvotes: 0
Reputation: 338288
You have the identity template (<xsl:template match="@* | node()">
) twice in your XSLT, you can remove the second one.
That being said, your logic goes like this
<xsl:for-each select ="./ADD/CONTACT[QUALIFIER='ST']">
<xsl:if test="./QUALIFIER='EM'">
<CONTACT_EMAIL>
<xsl:value-of select="NUMBER"/>
</CONTACT_EMAIL>
</xsl:if>
</xsl:for-each>
This cannot work. Judging from your example XML, there can't be a <CONTACT>
with qualifier equal to ST
that also has a qualifier equal to EM
.
You probably mean this:
<xsl:for-each select ="ADD/CONTACT[QUALIFIER='EM']">
<CONTACT_EMAIL>
<xsl:value-of select="NUMBER"/>
</CONTACT_EMAIL>
</xsl:for-each>
Notes
<xsl:apply-templates select="@* | node()" />
is what you want. I'd say it's not../
is redundant in XPath. Every path that does not start at the root of the document is relative to the current node by default anyway.Upvotes: 1