@@ -48,7 +48,7 @@ static LY_ERR reparse_or_expr(const struct ly_ctx *ctx, struct lyxp_expr *exp, u
4848static LY_ERR eval_expr_select (const struct lyxp_expr * exp , uint32_t * tok_idx , enum lyxp_expr_type etype ,
4949 struct lyxp_set * set , uint32_t options );
5050static LY_ERR moveto_resolve_model (const char * * qname , uint32_t * qname_len , const struct lyxp_set * set ,
51- const struct lys_module * * moveto_mod );
51+ const struct lysc_node * ctx_scnode , const struct lys_module * * moveto_mod );
5252static LY_ERR moveto_axis_node_next (const struct lyd_node * * iter , enum lyxp_node_type * iter_type ,
5353 const struct lyd_node * node , enum lyxp_node_type node_type , enum lyxp_axis axis , struct lyxp_set * set );
5454static LY_ERR moveto_node (struct lyxp_set * set , const struct lys_module * moveto_mod , const char * ncname ,
@@ -4112,33 +4112,11 @@ static LY_ERR
41124112xpath_derived_ident_module (const char * * qname , uint32_t * qname_len , const struct lyxp_set * set ,
41134113 const struct lys_module * * mod )
41144114{
4115- LY_CHECK_RET (moveto_resolve_model (qname , qname_len , set , mod ));
4116- if (* mod ) {
4117- /* prefixed identity */
4118- return LY_SUCCESS ;
4119- }
4120-
4121- switch (set -> format ) {
4122- case LY_VALUE_SCHEMA :
4123- case LY_VALUE_SCHEMA_RESOLVED :
4124- /* current module */
4115+ LY_CHECK_RET (moveto_resolve_model (qname , qname_len , set , set -> cur_node ? set -> cur_node -> schema : NULL , mod ));
4116+ if (!* mod ) {
4117+ /* unprefixed JSON identity */
4118+ assert (set -> format == LY_VALUE_JSON );
41254119 * mod = set -> cur_mod ;
4126- break ;
4127- case LY_VALUE_CANON :
4128- case LY_VALUE_JSON :
4129- case LY_VALUE_LYB :
4130- case LY_VALUE_STR_NS :
4131- /* inherit parent (context node) module */
4132- if (set -> cur_scnode ) {
4133- * mod = set -> cur_scnode -> module ;
4134- } else {
4135- * mod = set -> cur_mod ;
4136- }
4137- break ;
4138- case LY_VALUE_XML :
4139- /* all identifiers need to be prefixed */
4140- LOGVAL (set -> ctx , LYVE_DATA , "Non-prefixed identity \"%.*s\" in XML xpath found." , (int )* qname_len , * qname );
4141- return LY_EVALID ;
41424120 }
41434121
41444122 return LY_SUCCESS ;
@@ -5673,47 +5651,69 @@ xpath_pi_text(struct lyxp_set *set, enum lyxp_axis axis, uint32_t options)
56735651}
56745652
56755653/**
5676- * @brief Skip prefix and return corresponding model if there is a prefix . Logs directly.
5654+ * @brief Skip prefix and return corresponding model. Logs directly.
56775655 *
56785656 * XPath @p set is expected to be a (sc)node set!
56795657 *
56805658 * @param[in,out] qname Qualified node name. If includes prefix, it is skipped.
56815659 * @param[in,out] qname_len Length of @p qname, is updated accordingly.
56825660 * @param[in] set Set with general XPath context.
5661+ * @param[in] ctx_scnode Current context schema node (parent).
56835662 * @param[out] moveto_mod Expected module of a matching node.
56845663 * @return LY_ERR
56855664 */
56865665static LY_ERR
56875666moveto_resolve_model (const char * * qname , uint32_t * qname_len , const struct lyxp_set * set ,
5688- const struct lys_module * * moveto_mod )
5667+ const struct lysc_node * ctx_scnode , const struct lys_module * * moveto_mod )
56895668{
56905669 const struct lys_module * mod = NULL ;
56915670 const char * ptr ;
56925671 size_t pref_len ;
56935672
56945673 assert ((set -> type == LYXP_SET_NODE_SET ) || (set -> type == LYXP_SET_SCNODE_SET ));
56955674
5696- * moveto_mod = NULL ;
5675+ if ((ptr = ly_strnchr (* qname , ':' , * qname_len ))) {
5676+ /* specific module */
5677+ pref_len = ptr - * qname ;
5678+ mod = ly_resolve_prefix (set -> ctx , * qname , pref_len , set -> format , set -> prefix_data );
56975679
5698- ptr = ly_strnchr (* qname , ':' , * qname_len );
5699- if (!ptr ) {
5700- /* no prefix */
5701- return LY_SUCCESS ;
5702- }
5703-
5704- /* specific module */
5705- pref_len = ptr - * qname ;
5706- mod = ly_resolve_prefix (set -> ctx , * qname , pref_len , set -> format , set -> prefix_data );
5680+ /* check for errors and non-implemented modules, as they are not valid */
5681+ if (!mod || !mod -> implemented ) {
5682+ LOGVAL (set -> ctx , LY_VCODE_XP_INMOD , (int )pref_len , * qname );
5683+ return LY_EVALID ;
5684+ }
57075685
5708- /* check for errors and non-implemented modules, as they are not valid */
5709- if (!mod || !mod -> implemented ) {
5710- LOGVAL (set -> ctx , LY_VCODE_XP_INMOD , (int )pref_len , * qname );
5711- return LY_EVALID ;
5686+ * qname += pref_len + 1 ;
5687+ * qname_len -= pref_len + 1 ;
5688+ } else if (((* qname )[0 ] == '*' ) && (* qname_len == 1 )) {
5689+ /* all modules - special case */
5690+ mod = NULL ;
5691+ } else {
5692+ switch (set -> format ) {
5693+ case LY_VALUE_SCHEMA :
5694+ case LY_VALUE_SCHEMA_RESOLVED :
5695+ /* current module */
5696+ mod = set -> cur_mod ;
5697+ break ;
5698+ case LY_VALUE_CANON :
5699+ case LY_VALUE_JSON :
5700+ case LY_VALUE_LYB :
5701+ case LY_VALUE_STR_NS :
5702+ /* inherit parent (context node) module */
5703+ if (ctx_scnode ) {
5704+ mod = ctx_scnode -> module ;
5705+ } else {
5706+ /* JSON XPath is our own format (except for identityref), which supports node names matching all the modules */
5707+ mod = NULL ;
5708+ }
5709+ break ;
5710+ case LY_VALUE_XML :
5711+ /* all nodes need to be prefixed */
5712+ LOGVAL (set -> ctx , LYVE_DATA , "Non-prefixed node \"%.*s\" in XML xpath found." , (int )* qname_len , * qname );
5713+ return LY_EVALID ;
5714+ }
57125715 }
57135716
5714- * qname += pref_len + 1 ;
5715- * qname_len -= pref_len + 1 ;
5716-
57175717 * moveto_mod = mod ;
57185718 return LY_SUCCESS ;
57195719}
@@ -7683,20 +7683,21 @@ eval_literal(const struct lyxp_expr *exp, uint32_t *tok_idx, struct lyxp_set *se
76837683 *
76847684 * @param[in] nametest Nametest to check.
76857685 * @param[in] len Length of @p nametest.
7686+ * @param[in] ctx_scnode Found schema node as the context for the predicate.
76867687 * @param[in] set Context set.
76877688 * @param[in] key Expected key node.
76887689 * @return LY_SUCCESS on success,
76897690 * @return LY_ENOT if a predicate could not be compiled.
76907691 * @return LY_ERR on any error.
76917692 */
76927693static LY_ERR
7693- eval_name_test_try_compile_predicate_key (const char * nametest , uint32_t len , const struct lyxp_set * set ,
7694- const struct lysc_node * key )
7694+ eval_name_test_try_compile_predicate_key (const char * nametest , uint32_t len , const struct lysc_node * ctx_scnode ,
7695+ const struct lyxp_set * set , const struct lysc_node * key )
76957696{
76967697 const struct lys_module * mod ;
76977698
76987699 /* prefix (module) */
7699- LY_CHECK_RET (moveto_resolve_model (& nametest , & len , set , & mod ));
7700+ LY_CHECK_RET (moveto_resolve_model (& nametest , & len , set , ctx_scnode , & mod ));
77007701 if (mod && (mod != key -> module )) {
77017702 return LY_ENOT ;
77027703 }
@@ -7855,7 +7856,7 @@ eval_name_test_try_compile_predicates(const struct lyxp_expr *exp, uint32_t *tok
78557856
78567857 /* check key */
78577858 LY_CHECK_GOTO (rc = eval_name_test_try_compile_predicate_key (exp -> expr + exp -> tok_pos [e_idx ],
7858- exp -> tok_len [e_idx ], set , key ), cleanup );
7859+ exp -> tok_len [e_idx ], ctx_scnode , set , key ), cleanup );
78597860
78607861 ++ e_idx ;
78617862
@@ -8155,7 +8156,7 @@ eval_name_test_with_predicate(const struct lyxp_expr *exp, uint32_t *tok_idx, en
81558156 }
81568157
81578158 /* parse (and skip) module name */
8158- rc = moveto_resolve_model (& ncname , & ncname_len , set , & moveto_mod );
8159+ rc = moveto_resolve_model (& ncname , & ncname_len , set , NULL , & moveto_mod );
81598160 LY_CHECK_GOTO (rc , cleanup );
81608161
81618162 if ((ncname [0 ] == '*' ) && (ncname_len == 1 )) {
0 commit comments