Re: Check for null value and Check if child tag exists
Hi Priya, > I'm working on transfering data from and XML file to Oracle > Database. For this I need to convert my XML File into the canonical > form with the help of an XSLT. These are a few problems am facing > > 1) I need to be able to check if a particular tag has one or more > child tags and be able to get their values. You can check whether a particular element has a particular child element by trying to select the child element and testing the resulting node set. If the node set has a node in it, then it shows that the child element exists. If the node set doesn't have a node element, then it doesn't. Empty node sets evaluate as boolean false, while ones with nodes in evaluate as boolean true. > 2) I also need to be able to finout if a tag has a null value. By 'null value' you probably mean 'empty' - doesn't have any child nodes - no text, no elements. As above, you can test this by trying to create a node set of the child nodes that show whether it's a 'null' value or not. So if it's any nodes, then you could use: node() If you're only interested in text and element content (i.e. an element will still have a 'null' value if it holds a comment or a processing instruction), then you could use: *|text() Or if you're just concerned about the text content, and you don't care about whitespace, then you could use: normalize-space() This gets the string value of the context node and strips any leading or trailing whitespace, so it only returns true if there is some character data within the element. Anyway, that's just to answer your questions - as far as doing what you're trying to do is concerned, you are trying to get a row element for every City element in your input XML. If the City element has a parent Region element, then you want to use the @Name of that Region in the row, and the Country/@Name is used as well. The rowset element in the result corresponds to the World element in your source, so I'd have a World-matching template to create it. I'd apply templates to those City elements directly within that, to save the processor some work in trying to apply templates to everything: <xsl:template match="World"> <rowset> <xsl:apply-templates select="Country/City | Country/Region/City" /> </rowset> </xsl:template> [Note: you could use .//City instead, but the above is a little more efficient because it avoids the descendant axis.] Now, for each City element that's having templates applied to it, you want to create a row element in the result. So again, I'd make a template matching the City elements. In this template, you need to get the value of the City's Region (if it has one) and its Country. You can get these by moving up the node tree, using the ancestor:: axis: <xsl:template match="City"> <row> <country> <xsl:value-of select="ancestor::Country/@Name" /> </country> <region> <xsl:value-of select="parent::Region/@Name" /> </region> <city> <xsl:value-of select="@Name" /> </city> </row> </xsl:template> The one difference between the sample output that you gave and that given by the two templates above is that in your source you have: <Country Name="Afghanistan"> <Region Name="Herat"> <City Name="Herat" Time="GMT+04:30"></City> </Region> ... </Country> Giving: <row> <country>Afghanistan"> <region /> <city>Herat</city> </row> Whereas the above templates have Herat as the region as well as the city. I guess that you don't want to have the region specified if its Name is the same as the Name of the City? In that case, you need to change the above template to contain, the following, which tests whether the region is called the same as the city and only adds it if not: <region> <xsl:variable name="region" select="parent::Region/@Name" /> <xsl:if test="$region != @Name"> <xsl:value-of select="$region" /> </xsl:if> </region> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format