stevedlawrence commented on a change in pull request #373:
URL: https://github.com/apache/incubator-daffodil/pull/373#discussion_r417401624
##########
File path:
daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
##########
@@ -683,26 +683,109 @@ case class FNLocalName1(recipe: CompiledDPath, argType:
NodeInfo.Kind)
}
override def run(dstate: DState) {
- // Save off original state, which is the original
- // element/node that calls inputValueCalc with fn:local-name
- //
- val origState = dstate
+ // Save off original node, which is the original
+ // element/node that calls fn:local-name
+ val savedNode = dstate.currentNode
// Execute the recipe/expression which should
- // return a node/element whose local-name we want.
- //
+ // return a node/element whose local-name we want
recipe.run(dstate)
val localName = dstate.currentElement.name
+ dstate.setCurrentNode(savedNode)
if (localName.contains(":"))
throw new IllegalArgumentException("fn:local-name failed. " + localName
+ " is not a valid NCName as it contains ':'.")
- // The original state contains the node/element upon which
- // fn:local-name was called. This is where we should set
- // the value.
- //
- origState.setCurrentValue(localName)
+ dstate.setCurrentValue(localName)
+ }
+}
+
+/**
+ * Returns the namespace URI of the name of \$arg as an xs:string
+ * value.
+ *
+ * If the argument is omitted, it defaults to the context item (.).
+ * The behavior of the function if the argument is omitted is
+ * exactly the same as if the context item had been passed as
+ * the argument.
+ *
+ * If the node identified by \$arg is neither an element nor an
+ * attribute node, or it is an element or attribute node whose
+ * expanded-QName is in no namespace, then the function returns
+ * the zero-length xs:string value.
+ *
+ * Otherwise, the result will be the namespace URI of the
+ * expanded-QName of the node identified by \$arg returned as an
+ * xs:string value.
+ *
+ * The following errors may be raised when \$arg is omitted:
+ * - If the context item is absent, dynamic error [err:XPDY002]
+ * - If the context item is not a node, type error [err:XPTY004]
Review comment:
One other thing worth pointing out, I *think* there is a current
limiation in our DPath implementation where we can't tell if a subexpression
results to a node, we only keep track of the primitive type. For example, we
can't tell the difference between
```
fn:namespace-uri(0)
```
and
```
fn:namespace-uri(/path/to/int/element)
```
In both cases, I think all our implementation knows at schema compile time
is that the result of the argument is an int, we can't tell that one was a
constant int and the other is an element with an int type. And you can't just
check if the subexpression is constant, because the expression could be
something like this:
```
fn:namespace-uri(
if (somecondition) then /path/to/int/element
else /path/to/string/element)
)
```
I wonder if to support this check statically, our NodeInfo type system needs
a distinction between node types and non-node types, e.g. NodeInfo.Int vs
NodeInfo.NodeInt. That sounds like a big change so a runtime check is very
reasonable for this change.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]