24

XML file 1:

<?xml version="1.0"?>
<rentalProperties>
    <property contact ="1">
        <type>House </type>
        <price>420</price>
        <address>
            <streetNo>1</streetNo>
            <street>Wavell Street</street>
            <suburb>Box Hill</suburb>
            <state>VIC</state>
            <zipcode>3128</zipcode> 
        </address>
        <numberOfBedrooms>3</numberOfBedrooms>
        <numberOfBathrooms>1</numberOfBathrooms> 
        <garage>1</garage>   
    </property>

XML file 2:

<?xml version="1.0"?>
<rentalProperties>
    <property contact ="1">
        <type>House </type>
        <price>420</price>
        <address>1 wavell street,Box Hill,VIC,Australia</address>
        <numberOfBedrooms>3</numberOfBedrooms>
        <numberOfBathrooms>1</numberOfBathrooms> 
        <garage>1</garage>     
    </property>

How should i convert xml file 1 to xml fle 2 using xslt? i want to represent the address as the single line and add a new attribute [country- Australia] to end of the line. i did the rest of it . i'm struggling with address line

XSLT file:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" type="text/css" href="style.css">
    <xsl:template match="/">
        <rentalProperties>
            <property>
                <xsl:attribute name="contact"><xsl:value-of select='@contact'/></xsl:attribute>    
                <type><xsl:value-of select="type"/></type>
                <price><xsl:value-of select="price"/></price>
                <numberOfBedrooms><xsl:value-of select="numberOfBedrooms"/></numberOfBedrooms>
                <numberOfBathrooms><xsl:value-of select="numberOfBathrooms"/></numberOfBathrooms>
                <garage><xsl:value-of select="garage"/></garage>    
            </property>    
        </rentalProperties>    
    </xsl:template>
</xsl:stylesheet>

4 Answers 4

32

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="address">
  <xsl:copy>
   <xsl:value-of select=
   "concat(streetNo, ' ', street, ',',
           suburb,',', state,', Australia')
   "/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="address/node()"/>
</xsl:stylesheet>

when applied on the provided XML document:

<rentalProperties>
    <property contact ="1">
        <type>House </type>
        <price>420</price>
        <address>
            <streetNo>1</streetNo>
            <street>Wavell Street</street>
            <suburb>Box Hill</suburb>
            <state>VIC</state>
            <zipcode>3128</zipcode>
        </address>
        <numberOfBedrooms>3</numberOfBedrooms>
        <numberOfBathrooms>1</numberOfBathrooms>
        <garage>1</garage>
    </property>
</rentalProperties>

produces the wanted, correct result:

<rentalProperties>
   <property contact="1">
      <type>House </type>
      <price>420</price>
      <address>1 Wavell Street,Box Hill,VIC, Australia</address>
      <numberOfBedrooms>3</numberOfBedrooms>
      <numberOfBathrooms>1</numberOfBathrooms>
      <garage>1</garage>
   </property>
</rentalProperties>

Explanation: Using and overriding the identity rule.

Sign up to request clarification or add additional context in comments.

2 Comments

Is it possible to also include the xml header in the output: <?xml version="1.0" encoding="iso-8859-1"?>
@mgouin, It is called "XML declaration". Yes, just remove the omit-xml-declaration="yes" attribute from the <xsl:output> instruction
4

You could introduce a new template for the address block using

<xsl:template match="address">
    <xsl:value-of select="streetNo" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="street" />
    <xsl:text>,</xsl:text>
    <xsl:value-of select="suburb" />
    <xsl:text>,</xsl:text>
    <xsl:value-of select="state" />
    <xsl:text>,</xsl:text>
    <xsl:value-of select="zipcode" />
</xsl:template>

and call it with

<xsl:apply-templates select="address" />

before the <numberOfBedrooms> element. This can also be done using the concat function, whereas the correct syntax I don't remember right now.

Comments

1

You can try something like:

<address>
    <xsl:for-each select="address/*">
       <xsl:value-of select="."/>, 
    </xsl:for-each>
    Australia
</address>

This loops over all the children of the address tag in xml1.

Comments

-3
<rentalProperties>
    <property contact="1">
        <type>House </type>
        <price>420</price>
        <address>1 Wavell Street,Box Hill,VIC,3128</address>
        <numberOfBedrooms>3</numberOfBedrooms>
        <numberOfBathrooms>1</numberOfBathrooms> 
        <garage>1</garage>   
    </property>
</rentalProperties>

2 Comments

Code-only answers can almost always be improved by adding a few explanatory sentences; you can edit your answer to do so.
What's the solution here?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.