TulioVargas
TulioVargas

Reputation: 179

XSLT take content xml tag from different structure

I was wondering how I can organise the XML using XSLT <xsl:stylesheet version="2.0"

Get the first position address tag in /root/body/shipTo/destination/address and add it to the /root/header/address, however, some fields must be created, renamed, and insert validation.

<root>
    <header>
        <address>
            <street/>
            <street3/>
            <phone/>
            <Region>
                <RegionCoded/>
            </Region>
        </address>
    </header>
    <body>
        <shipTo>
            <destination>
                <address>
                    <street>AAA</street>
                    <street2>BBB</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
            <destination>
                <address>
                    <street>CDA</street>
                    <street2>YYY</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
            <destination>
                <address>
                    <street>PPP</street>
                    <street2>ZZZ</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
        </shipTo>
    </body>
</root>

The desired result would be something like the XML below:

<root>
    <header>
        <address>
            <street>AAA</address> <!-- street -->
            <name1>BBB</name1> <!-- street2 -->
            <street3>123</street3> <!-- street99 -->
            <phone>
                <mobile>1999999999</mobile> <!-- phone -->
            </phone>
            <Region> <!-- Region -->
                <RegionCoded>00</RegionCoded>
            </Region>
            <emailFROM>[email protected]</emailFROM> <!-- check if is a valid email -->
            <merge>AAA | BBB</merge>  <!-- street + street2 -->
        </address>
    </header>
    <body>
        <shipTo>
            <destination>
                <address>
                    <street>AAA</street>
                    <street2>BBB</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
            <destination>
                <address>
                    <street>CDA</street>
                    <street2>YYY</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
            <destination>
                <address>
                    <street>PPP</street>
                    <street2>ZZZ</street2>
                    <street99>123</street99>
                    <phone>1999999999</phone>
                    <Region>
                        <RegionCoded>00</RegionCoded>
                    </Region>
                    <email>[email protected]</email>
                </address>
            </destination>
        </shipTo>
    </body>
</root>

There is a validation in the email tag, is it possible to add a regex to validate it? like: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

Upvotes: 0

Views: 27

Answers (1)

Sebastien
Sebastien

Reputation: 2714

Here's one way this could be done:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="header/address">
    <xsl:variable name="source" select="//body/shipTo/destination[1]/address"/>
    <xsl:copy>
      <street><xsl:value-of select="$source/street"/></street> <!-- street -->
      <name1><xsl:value-of select="$source/street2"/></name1> <!-- street2 -->
      <street3><xsl:value-of select="$source/street99"/></street3> <!-- street99 -->
      <phone>
          <mobile><xsl:value-of select="$source/phone"/></mobile> <!-- phone -->
      </phone>
      <Region> <!-- Region -->
          <RegionCoded><xsl:value-of select="$source/Region/RegionCoded"/></RegionCoded>
      </Region>
      <emailFROM><xsl:value-of select="$source/email"/></emailFROM>
      <emailValid><xsl:value-of select="matches(upper-case($source/email),'^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$')"/></emailValid> <!-- check if is a valid email -->
      <merge><xsl:value-of select="concat($source/street,' | ',$source/street2)"/></merge>  <!-- street + street2 -->
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/3NgtZRg

Note: I used the regex from this answer: How to validate an email address using XSLT 2.0?

Upvotes: 1

Related Questions