Instead of transforming one element at a time, you may have a series of elements and it would not be flexible to visit each element. In fact. it may be impossible to visit each element if the list of elements can grow or shrink any time. If the elements are child nodes, you can apply a loop to their parent and visit each child node. To support this operation, XSLT provides an element named for-each. The syntax to use the for-each element is: <xsl:for-each select = Expression </xsl:for-each> As done for the elements so far, the select attribute allows you to specify the element to use. Consider the following XML document saved as RealEstate2.xml: Private Sub cmdCreateXMLFile_Click() On Error GoTo cmdCreateXMLFile_Error Open "C:\RealEstate\RealEstate2.xml" For Output As #1 Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>" Print #1, "<?xml-stylesheet href=""C:\RealEstate\RealEstate2.xsl"" type=""text/xsl"" ?>" Print #1, "<RealEstate>" Print #1, " <ListingTitle>Real Estate - Properties Listing</ListingTitle>" Print #1, " <Property>" Print #1, " <PropertyNumber>808420</PropertyNumber>" Print #1, " <PropertyType>Single Family</PropertyType>" Print #1, " <Bedrooms>4</Bedrooms>" Print #1, " <Bathrooms>2.50</Bathrooms>" Print #1, " <City>Silver Spring</City>" Print #1, " <State>MD</State>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>209538</PropertyNumber>" Print #1, " <PropertyType>Townhouse</PropertyType>" Print #1, " <Bedrooms>3</Bedrooms>" Print #1, " <Bathrooms>2.50</Bathrooms>" Print #1, " <City>Washington</City>" Print #1, " <State>DC</State>" Print #1, " <MarketValue>258605</MarketValue>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>740514</PropertyNumber>" Print #1, " <PropertyType>Condominium</PropertyType>" Print #1, " <Bedrooms>1</Bedrooms>" Print #1, " <Bathrooms>1.00</Bathrooms>" Print #1, " <City>McLean</City>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>407384</PropertyNumber>" Print #1, " <PropertyType>Single Family</PropertyType>" Print #1, " <Bedrooms>5</Bedrooms>" Print #1, " <Bathrooms>3.50</Bathrooms>" Print #1, " <City>Silver Spring</City>" Print #1, " <MarketValue>622015</MarketValue>" Print #1, " </Property>" Print #1, "</RealEstate>" Close #1 Exit Sub cmdCreateXMLFile_Error: MsgBox "There was a problem when trying to create the XML file." & vbCrLf & _ "Make sure you report the error as follows:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub This is a typical list to which new elements (new houses in this case) can be added any time and undesired elements (such as sold houses) can be deleted any time. So it is not practical to visit each node. In fact, elements on the same level may not have the same child nodes and child nodes may not be arranged in the same order in each element. You can first create an XSLT with a placeholder for each element. Here is an example: <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Real Estate - Properties Listing</title> </head> <body> <h3>Real Estate - Peoperties Lising</h3> <table> <tr> <td><b>Prop #</b></td> <td><b>Type</b></td> <td><b>Bedrooms</b></td> <td><b>Bathrooms</b></td> <td><b>City</b></td> <td><b>State</b></td> <td><b>Market Value</b></td> </tr> <tr> <td>Placeholder for property #</td> <td>Placeholder for property type</td> <td>Placeholder for number of bedrooms</td> <td>Placeholder for number of bathrooms</td> <td>Placeholder for the city</td> <td>Placeholder for state</td> <td>Placeholder for house house price (value in the market)</td> </tr> </table> </body> </html> </xsl:template> </xsl:stylesheet> A solution is to use a for-each element to visit each child node. This can be done as follows: Private Sub cmdTransform_Click() On Error GoTo cmdTransform_Error Open "C:\RealEstate\RealEstate2.xsl" For Output As #1 Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>" Print #1, "<xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">" Print #1, " <xsl:template match=""/"">" Print #1, " <html>" Print #1, " <head>" Print #1, " <title>Real Estate - Peoperties Listing</title>" Print #1, " </head>" Print #1, " <body>" Print #1, " <div align=""center"">" Print #1, " <h3><xsl:value-of select=""RealEstate/ListingTitle"" /></h3>" Print #1, " <table>" Print #1, " <tr bgcolor=""#B8B8B8"">" Print #1, " <td width=""60"" align=""center""><b>Prop #</b></td>" Print #1, " <td width=""100""><b>Type</b></td>" Print #1, " <td><b>Bedrooms</b></td>" Print #1, " <td><b>Bathrooms</b></td>" Print #1, " <td><b>City</b></td>" Print #1, " <td><b>State</b></td>" Print #1, " <td><b>Market Value</b></td>" Print #1, " </tr>" Print #1, " <xsl:for-each select=""RealEstate/Property"">" Print #1, " <tr bgcolor=""#E2E2E2"">" Print #1, " <td align=""center""><xsl:value-of select=""PropertyNumber"" /></td>" Print #1, " <td><xsl:value-of select=""PropertyType"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""Bedrooms"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""Bathrooms"" /></td>" Print #1, " <td><xsl:value-of select=""City"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""State"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""MarketValue"" /></td>" Print #1, " </tr>" Print #1, " </xsl:for-each>" Print #1, " </table>""" Print #1, " </div>" Print #1, " </body>" Print #1, " </html>" Print #1, " </xsl:template>" Print #1, "</xsl:stylesheet>" Close #1 Exit Sub cmdTransform_Error: MsgBox "There was a problem to create the XSLT file. Please report the problem as:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub This would produce:
As you may know already, an XML atribute is a child element created inside of the start tag of a node. As a reminder, here is an example of an attribute: Private Sub cmdCreateXMLFile_Click() On Error GoTo cmdCreateXMLFile_Error Open "C:\RealEstate\RealEstate3.xml" For Output As #1 Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>" Print #1, "<?xml-stylesheet href=""C:\RealEstate\RealEstate2.xsl"" type=""text/xsl"" ?>" Print #1, "<RealEstate>" Print #1, " <ListingTitle Category=""Regional Listing"">Real Estate - Properties Listing</ListingTitle>" Print #1, "</RealEstate>" Close #1 Exit Sub cmdCreateXMLFile_Error: MsgBox "There was a problem when trying to create the XML file." & vbCrLf & _ "Make sure you report the error as follows:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub Because an attribute is related to the element, to access an attribute in an extensible style sheet, you can precede its name with the @ sign, but you must indicate its parent element. This can be done in the template element where you would provide the name of its parent element. Here is an example: Private Sub cmdTransform_Click() On Error GoTo cmdTransform_Error Open "C:\RealEstate\RealEstate3.xsl" For Output As #1 Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>" Print #1, "<xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" version=""1.0"">" Print #1, " <xsl:template match=""ListingTitle"">" Print #1, " <html>" Print #1, " <head>" Print #1, " <title>Real Estate - Peoperties Listing</title>" Print #1, " </head>" Print #1, " <body>" Print #1, " <div align=""center"">" Print #1, " <xsl:value-of select=""@Category"" />" Print #1, " </div>" Print #1, " </body>" Print #1, " </html>" Print #1, " </xsl:template>" Print #1, "</xsl:stylesheet>" Close #1 Exit Sub cmdTransform_Error: MsgBox "There was a problem to create the XSLT file. Please report the problem as:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub In the same way, you can transform other XML attributes from your style sheet. Also you can format the values of the attributes any way you want. Here are examples: XML File: RealEstate4.xml Private Sub cmdCreateXMLFile_Click() On Error GoTo cmdCreateXMLFile_Error Open "C:\RealEstate\RealEstate4.xml" For Output As #1 Print #1, "<?xml version='1.0' encoding='UTF-8'?>" Print #1, "<?xml-stylesheet href='C:\RealEstate\RealEstate4.xsl' type='text/xsl' ?>" Print #1, "<RealEstate>" Print #1, " <RegionTitle BuiltFrom='1970'" Print #1, " BuiltTo = '2020'" Print #1, " PriceFrom = '200000'" Print #1, " PriceTo='800000'>Washington, DC Metropolitan Area</RegionTitle>" Print #1, "</RealEstate>" Close #1 Exit Sub cmdCreateXMLFile_Error: MsgBox "There was a problem when trying to create the XML file." & vbCrLf & _ "Make sure you report the error as follows:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub XSLT File: RealEstate4.xsl Private Sub cmdTransform_Click() On Error GoTo cmdTransform_Error Open "C:\RealEstate\RealEstate4.xsl" For Output As #1 Print #1, "<?xml version='1.0' encoding='UTF-8'?>" Print #1, "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>" Print #1, " <xsl:template match='RegionTitle'>" Print #1, " <html>" Print #1, " <head>" Print #1, " <title>Real Estate - Properties Listing</title>" Print #1, " </head>" Print #1, " <body>" Print #1, " <p><strong>Year Range From </strong><xsl:value-of select='@BuiltFrom' /><strong> to </strong><xsl:value-of select='@BuiltTo' /></p>" Print #1, " <p><strong>Price Range From</strong> $<xsl:value-of select='@PriceFrom' /><strong> to </strong>$<xsl:value-of select='@PriceTo' /></p>" Print #1, " </body>" Print #1, " </html>" Print #1, " </xsl:template>" Print #1, "</xsl:stylesheet>" Close #1 Exit Sub cmdTransform_Error: MsgBox "There was a problem to create the XSLT file. Please report the problem as:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub In the above examples, we considered only one element with attributes. Most of the time, you may have different elements that have attributes. In such a case, you can specify the value of the match attribute of the template as the root or an ancestor. Consider the following version of the XML document (saved as RealEstate4.xml): Private Sub cmdCreateXMLFile_Click() On Error GoTo cmdCreateXMLFile_Error Open "C:\RealEstate\RealEstate4.xml" For Output As #1 Print #1, "<?xml version='1.0' encoding='UTF-8'?>" Print #1, "<?xml-stylesheet href='C:\RealEstate\RealEstate4.xsl' type='text/xsl' ?>" Print #1, "<RealEstate>" Print #1, " <ListingTitle Category='Regional Listing'>Real Estate - Properties Listing</ListingTitle>" Print #1, " <RegionTitle BuiltFrom='1970'" Print #1, " BuiltTo = '2020'" Print #1, " PriceFrom = '200000'" Print #1, " PriceTo='800000'>Washington, DC Metropolitan Area</RegionTitle>" Print #1, "</RealEstate>" Close #1 Exit Sub cmdCreateXMLFile_Error: MsgBox "There was a problem when trying to create the XML file." & vbCrLf & _ "Make sure you report the error as follows:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub To access an attribute, use the following formula: ParentElement/@AttributeName Here are example (this is a new version of the previous XSLT file: RealEstate4.xsl: Private Sub cmdTransform_Click() On Error GoTo cmdTransform_Error Open "C:\RealEstate\RealEstate4.xsl" For Output As #1 Print #1, "<?xml version='1.0' encoding='UTF-8'?>" Print #1, "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>" Print #1, " <xsl:template match='RealEstate'>" Print #1, " <html>" Print #1, " <head>" Print #1, " <title>Real Estate - Properties Listing</title>" Print #1, " </head>" Print #1, " <body>" Print #1, " <xsl:value-of select='ListingTitle/@Category' />" Print #1, " <table>" Print #1, " <tr>" Print #1, " <td><strong>Year Range From:</strong></td>" Print #1, " <td><xsl:value-of select='RegionTitle/@BuiltFrom' /></td>" Print #1, " </tr>" Print #1, " <tr>" Print #1, " <td align='right'><strong>to:</strong></td>" Print #1, " <td><xsl:value-of select='RegionTitle/@BuiltTo' /></td>" Print #1, " </tr>" Print #1, " <tr>" Print #1, " <td><strong>Price Range From:</strong></td>" Print #1, " <td>$<xsl:value-of select='RegionTitle/@PriceFrom' /></td>" Print #1, " </tr>" Print #1, " <tr>" Print #1, " <td align='right'><strong>to:</strong></td>" Print #1, " <td>$<xsl:value-of select='RegionTitle/@PriceTo' /></td>" Print #1, " </tr>" Print #1, " </table>" Print #1, " </body>" Print #1, " </html>" Print #1, " </xsl:template>" Print #1, "</xsl:stylesheet>" Close #1 Exit Sub cmdTransform_Error: MsgBox "There was a problem to create the XSLT file. Please report the problem as:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub This would produce: In the same, you can visit the attributes in an element and access each of them using the @ sign. Consider the following document saved as RealEstate5.xml: Private Sub cmdCreateXMLFile_Click() On Error GoTo cmdCreateXMLFile_Error Open "C:\RealEstate\RealEstate5.xml" For Output As #1 Print #1, "<?xml version='1.0' encoding='UTF-8'?>" Print #1, "<?xml-stylesheet href='C:\RealEstate\RealEstate5.xsl' type='text/xsl' ?>" Print #1, "<RealEstate>" Print #1, " <ListingTitle>Real Estate - Peoperties Listing</ListingTitle>" Print #1, " <Property>" Print #1, " <PropertyNumber>808420</PropertyNumber>" Print #1, " <PropertyType>Single Family</PropertyType>" Print #1, " <Bedrooms>4</Bedrooms>" Print #1, " <Bathrooms>2.50</Bathrooms>" Print #1, " <City Locality=""White Oak"" Street=""New Hampshire Ave"">Silver Spring</City>" Print #1, " <State ZIPCode=""20904"">MD</State>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>209538</PropertyNumber>" Print #1, " <PropertyType>Townhouse</PropertyType>" Print #1, " <Bedrooms>3</Bedrooms>" Print #1, " <Bathrooms>2.50</Bathrooms>" Print #1, " <City Locality=""Georgetown"" Street=""M Str. N.W."">Washington</City>" Print #1, " <State>DC</State>" Print #1, " <MarketValue>258605</MarketValue>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>740514</PropertyNumber>" Print #1, " <PropertyType>Condominium</PropertyType>" Print #1, " <Bedrooms>1</Bedrooms>" Print #1, " <Bathrooms>1.00</Bathrooms>" Print #1, " <City Locality=""Seven-Corner"">McLean</City>" Print #1, " </Property>" Print #1, " <Property>" Print #1, " <PropertyNumber>407384</PropertyNumber>" Print #1, " <PropertyType>Single Family</PropertyType>" Print #1, " <Bedrooms>5</Bedrooms>" Print #1, " <Bathrooms>3.50</Bathrooms>" Print #1, " <City Locality=""Takoma Park Metro Station"" Street=""East-West Hwy"">Silver Spring</City>" Print #1, " <MarketValue>622015</MarketValue>" Print #1, " </Property>" Print #1, "</RealEstate>" Close #1 Exit Sub cmdCreateXMLFile_Error: MsgBox "There was a problem when trying to create the XML file." & vbCrLf & _ "Make sure you report the error as follows:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub Notice that some elements have no attribute and some elements have one or more attributes. There are various ways you can access the attribute of an element in your extensible style sheet. Here are examples: Private Sub cmdTransform_Click() On Error GoTo cmdTransform_Error Open "C:\RealEstate\RealEstate5.xsl" For Output As #1 Print #1, "<?xml version=""1.0""?>" Print #1, "<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">" Print #1, " <xsl:template match=""/"">" Print #1, " <html>" Print #1, " <head>" Print #1, " <title>Real Estate - Peoperties Listing</title>" Print #1, " </head>" Print #1, " <body>" Print #1, " <div align=""center"">" Print #1, " <h3><xsl:value-of select=""RealEstate/ListingTitle"" /></h3>" Print #1, " <table>" Print #1, " <tr bgcolor=""#B8B8B8"">" Print #1, " <td width=""60"" align=""center""><b>Prop #</b></td>" Print #1, " <td width=""100""><b>Type</b></td>" Print #1, " <td><b>Bedrooms</b></td>" Print #1, " <td><b>Bathrooms</b></td>" Print #1, " <td><b>City</b></td>" Print #1, " <td><b>Locality</b></td>" Print #1, " <td><b>On/Near</b></td>" Print #1, " <td><b>State</b></td>" Print #1, " <td><b>Market Value</b></td>" Print #1, " </tr>" Print #1, " <xsl:for-each select=""RealEstate/Property"">" Print #1, " <tr bgcolor=""#E2E2E2"">" Print #1, " <td align=""center""><xsl:value-of select=""PropertyNumber"" /></td>" Print #1, " <td><xsl:value-of select=""PropertyType"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""Bedrooms"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""Bathrooms"" /></td>" Print #1, " <td><xsl:value-of select=""City"" /></td>" Print #1, " <td><xsl:value-of select=""City/@Locality"" /></td>" Print #1, " <td><xsl:value-of select=""City/@Street"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""State"" /></td>" Print #1, " <td align=""center""><xsl:value-of select=""MarketValue"" /></td>" Print #1, " </tr>" Print #1, " </xsl:for-each>" Print #1, " </table>" Print #1, " </div>" Print #1, " </body>" Print #1, " </html>" Print #1, " </xsl:template>" Print #1, "</xsl:stylesheet>" Close #1 Exit Sub cmdTransform_Error: MsgBox "There was a problem to create the XSLT file. Please report the problem as:" & vbCrLf & _ "Error #: " & Err.Number & vbCrLf & _ "Description: " & Err.Description, _ vbOKOnly Or vbInformation, _ "Extensible Markup Language" Resume Next End Sub This would produce: In the XSLT standards, the formula to transform an attribute is: <xsl:attribute name = "attribute-name" namespace = "uri-reference"> </xsl:attribute> The name attribute is required. It can be a qualified or a local name. The namespace attribute is the address that defines where the transformating attribute was defined. |
|
|||||
|