Subject: Re: [xsl] An XPath expression that avoids writing special casecode? From: "Roger L Costello costello@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 18 Jun 2021 13:31:15 -0000 |
Hi Mukul, I tried your suggestion. For this XML document: <Document> <Row> <Cell> <Data>aviation</Data> </Cell> <Cell/> </Row> </Document> I evaluated the following XPath expression in Oxygen XML: /Document/Row[Cell[1]/Data eq 'aviation'][Cell[2]/string(Data) eq ''] Oxygen XML returned the desired row: <Row> <Cell> <Data>aviation</Data> </Cell> <Cell/> </Row> Fantastic! Question: Below are two XPath expressions. The first is the one that Mukul recommended and it returns the desired row. The second is the one that I created and it fails. The only difference between the two XPath expressions is string(Data) versus Data. Why does the former work whereas the later fails? /Document/Row[Cell[1]/Data eq 'aviation'][Cell[2]/string(Data) eq ''] /Document/Row[Cell[1]/Data eq 'aviation'][Cell[2]/Data eq ''] /Roger From: Mukul Gandhi mukulg@xxxxxxxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Sent: Friday, June 18, 2021 3:28 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: [EXT] Re: [xsl] An XPath expression that avoids writing special casecode? On Thu, Jun 17, 2021 at 7:36 PM Roger L Costello mailto:costello@xxxxxxxxx <mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: B My XML document contains a bunch of <Row> elements, like so: <Document> B B ... B B <Row> B B B B <Cell> B B B B B B <Data>airport</Data> B B B B </Cell> B B B B <Cell> B B B B B B <Data>airports</Data> B B B B </Cell> B B </Row> B B ... </Document> I want to fetch the Row whose Cell[1]/Data is 'airport' and whose Cell[2]/Data is 'airports'. So I created this XPath expression: /Document/Row[Cell[1]/Data eq 'airport'][Cell[2]/Data eq 'airports'] I do this kind of fetching operation often, so I created a function to fetch the desired Row: <xsl:function name="f:getRow"> B B <xsl:param name="element"/> B B <xsl:param name="parent"/> B B <xsl:sequence select="$document/Row[Cell[1]/Data eq $element][Cell[2]/Data eq $parent]" /> </xsl:function> I call the function this way: <xsl:sequence select="f:getRow('airport', 'airports')" /> Sometimes there is an element that doesn't have a parent. That is, sometimes I'd like to fetch a Row in which Cell[2] is empty, like this: B B <Row> B B B B <Cell> B B B B B B <Data>aviation</Data> B B B B </Cell> B B B B <Cell/> B B </Row> Then this call to f:getRow fails: <xsl:sequence select="f:getRow('aviation', '')" />B B B B <!-- Those are two apostrophes within the parentheses --> Clearly I need to modify f:getRow. I could add special case code to test $parent to see if it is empty (the '' string) and do one thing, and if it's not empty do another thing. But I wonder if there is a more elegant solution that doesn't involve special case code? Is there a way to modify the XPath expression in f:getRow such that it fetches the correct Row regardless of whether $parent is empty or not? Testing with XSLT 2.0. Below is an example, for the solution you may be looking for, XML input document, <Document> B B <Row> B B B B <Cell> B B B B B <Data>airport</Data> B B B B </Cell> B B B B <Cell> B B B B B <Data>airports</Data> B B B B </Cell> B B </Row> B B <Row> B B B B <Cell> B B B B B <Data>airport</Data> B B B B </Cell> B B B B <Cell> B B B B B <Data>ABC</Data> B B B B </Cell> B B </Row> B B <Row> B B B <Cell> B B B B B <Data>aviation</Data> B B B </Cell> B B B <Cell/> B B </Row> </Document>B XSLT stylesheet, <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" B B B B B B B B B B B B B xmlns:f="http://test_fn" B B B B B B B B B B B B B exclude-result-prefixes="f" B B B B B B B B B B B B B version="2.0"> B B <xsl:output method="xml" indent="yes"/> B B B B <xsl:variable name="document" select="/Document"/> B B <xsl:template match="/"> B B B <result> B B B B B <xsl:copy-of select="f:getRow('airport', 'airports')"/> B B B B B <xsl:copy-of select="f:getRow('aviation', '')"/> B B B </result> B B </xsl:template> B B B B <xsl:function name="f:getRow"> B B B <xsl:param name="element"/> B B B <xsl:param name="parent"/> B B B <xsl:sequence select="$document/Row[Cell[1]/Data eq $element][Cell[2]/string(Data) eq $parent]" /> B B </xsl:function> </xsl:stylesheet> The output of above XSLT transformation is following, <?xml version="1.0" encoding="UTF-8"?> <result> B B <Row> B B B B <Cell> B B B B B <Data>airport</Data> B B B B </Cell> B B B B <Cell> B B B B B <Data>airports</Data> B B B B </Cell> B B </Row> B B <Row> B B B <Cell> B B B B B <Data>aviation</Data> B B B </Cell> B B B <Cell/> B B </Row> </result> -- Regards, Mukul Gandhi http://www.mulberrytech.com/xsl/xsl-list http://lists.mulberrytech.com/unsub/xsl-list/673357 ()
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] An XPath expression that , Martin Honnen martin | Thread | Re: [xsl] An XPath expression that , Wendell Piez wapiez@ |
Re: [xsl] An XPath expression that , Martin Honnen martin | Date | Re: [xsl] An XPath expression that , Wendell Piez wapiez@ |
Month |