Re: Fwd: Pattern matching error in xsl:key
Chapman Flack <chap-JULfBfA8satPFr4CO1/[email protected]> Sun, 6 Sep 2020 11:51:03 -0400
| Newsgroups | gmane.text.xml.saxon.help |
|---|---|
| Message-ID | <[email protected]> |
On 09/05/20 14:37, Ihe Onwuka wrote: > That's the reason the spec gives. I asked for the logical reason. > > Perhaps you feel they are one and the same to me they are not because they > produce the illogical end result that two things that are obviously equal > are not Here's why I agree it's the logical reason. The best way anyone has ever come up with to design a language that is usable for writing predictable and dependable programs is to give it rules that are clearly stated and always applied. That doesn't make it effortless to learn or use: you do have to learn what the rules are. But once you have, you always know what it's going to do. In this case, you have to keep in mind there are two specs involved. XML has a spec. Already had one before XSLT was specified. And XSLT also has a spec (for this purpose, we'll say XPath is part of that). AND when you write out XSLT, you write it in XML. You write a program for operating on XML, in the language XSLT, and that program is written out in XML form itself. That's just the basic landscape; anybody using it has to remember that. So the comment > I am comparing parameters whose values are 4.0 and 4.1 respectively to > attributes whose values are 4.0 and 4.1 respectively. Saxon has made it's > own assumptions about what types they are isn't really on point. Saxon hasn't made assumptions about what types they are, it has given them the types of what you wrote. This comment was more on point: > you've basically got a situation where the spec is assigning > different types to the same identical value because they are > placed in different constructs. Well yes, yes exactly. As the human, it's your job to learn what the different constructs mean. XSLT is just always going to do what you have told it to do. In your *data*, <changes from="math:exp(1)" to="math:pi()"/> is just the XML document you're operating on, it's data, and that's an XML element with two attributes, they are xs:untypedAtomic and each one has a value that starts with 'm' and ends with ')'. In your *program*, <xsl:param name="source" select="math:exp(1)"/> <xsl:param name="target" select="math:pi()"/> is in the form of XML, sure, but it isn't just data, it's your program, with the semantics of XSLT. Those select attributes are expressions, and they have values of type xs:double, somewhere around 2.71 and 3.14, and will not match the <changes> element above. It is up to you to remember where you're writing literals and where you're writing expressions. That can't really be made easier. The language rules are consistent and once you are using them consistently they won't surprise you anymore. Now, there's a choice of different ways the <param> could be rewritten. As suggested upthread, just doing this won't work: <xsl:param name="target" select="4.0" as="xs:string"/> It would earn you a "required type is xs:string, supplied value is xs:decimal" error, just as String target = 4.0; would in Java. Here are two other choices: <xsl:param name="target" select="4.0 cast as xs:string"/> <xsl:param name="target" as="xs:string">4.0</xsl:param> Both of them will give you a string, but they will give you different strings. The first one is an expression that produces 4.0 as a decimal value and then casts it to xs:string; by the rules of number-to-string casting, that will come out "4", not "4.0". The second one will take the xs:untyped 4.0 appearing in the content and cast it directly to xs:string, producing "4.0". Probably that is the construct you would want to use. Once those rules are familiar, you can confidently rely on them. Regards, -Chap