Skip to content

question about rb_sort_clb #2476

Open
Open

Description

@ExclusiveDY

using version: libyang 3
origin xml: C is list, C-type is key, the type of C-type is enumeration : [XX, 1], [YY, 2]

<A xmlns='urn:ietf:params:xml:ns:yang:A'>
  <B>
	<C>
	  <C-type>XX</C-type>
	</C>
	<C>
	  <C-type>YY</C-type>
	</C>
  </C>
</A>

When I convert this XML into a libyang tree ,I found that the libyang tree became the following.

<A xmlns='urn:ietf:params:xml:ns:yang:A'>
  <B>
	<C>
	  <C-type>YY</C-type>
	</C>
	<C>
	  <C-type>XX</C-type>
	</C>
  </C>
</A>

I found that the reason for this behavior is that the lyplg_type_sort_enum function sorts the enumeration types from largest to smallest, while for the string type, its sorting function lyplg_type_compare_simple sorts from smallest to largest. For the boolean and decimal64 types, the sorting is also from smallest to largest.
Question:
1、I would like to know what considerations led to this difference?
2、I expect the libyang tree to maintain the original XML order. how should I do this?

Looking forward to your reply. Thanks.

Activity

  1. michalvasko commented on Jan 22, 2026

    @michalvasko
    Member

    lyplg_type_sort_enum function sorts the enumeration types from largest to smallest

    Not true, it is sorted based on the enum value, the string name is ignored. All the types should be sorted in ascending order.

    I expect the libyang tree to maintain the original XML order. how should I do this?

    You must then define the list as ordered-by user.

  2. ExclusiveDY commented on Jan 22, 2026

    @ExclusiveDY
    Author

    Not true, it is sorted based on the enum value, the string name is ignored. All the types should be sorted in ascending order.

    The enumeration type in the example above is defined as follows, but it appears in descending order. Why is this?

      typedef Ctype {
        type enumeration {
          enum "XX" {
            value 1;
          }
          enum "YY" {
            value 2;
          }
      }
    

    You must then define the list as ordered-by user.

    Is there any interface I can set up? Or do I need to implement the sorting method myself?

  3. michalvasko commented on Jan 22, 2026

    @michalvasko
    Member

    Why is this?

    Okay, I do not know what you are doing exactly. I have tested it myself, you can try it, too. The data are ordered in ascending order based on the enum value.

    Is there any interface I can set up? Or do I need to implement the sorting method myself?

    You can implement a type plugin for a specific typedef. In it you can define your own sorting callback and sort however you want. That is true for system-ordered lists. If you define a user-ordered list, it will always keep the same order of data that were received from the input.

  4. ExclusiveDY commented on Jan 26, 2026

    @ExclusiveDY
    Author

    Okay, I do not know what you are doing exactly. I have tested it myself, you can try it, too. The data are ordered in ascending order based on the enum value.

    The original message is as follows.

    <?xml version='1.0' encoding='UTF-8'?>
    <rpc message-id='' xmlns='urn:ietf:params:xml:ns:netconf:base:1.0'>
      <edit-config>
        <target>
          <running/>
        </target>
        <config>
    		<A xmlns='urn:ietf:params:xml:ns:yang:A'>
    		  <B>
    			<C>
    			  <C-type>XX</C-type>
    			</C>
    			<C>
    			  <C-type>YY</C-type>
    			</C>
    		  </C>
    		</A>
        </config>
      </edit-config>
    </rpc>
    

    My test procedure is as follows:

    ly_in *in = nullptr;
    lyd_node *tree = nullptr;
    lyd_node *ntf = nullptr;
    if (ly_in_new_memory(XMLBUF_TO_STR(xmlBuf), &in) != LY_SUCCESS) {
    .....
     }
    if (lyd_parse_op(ctx, nullptr, in, LYD_XML, options, &tree, &ntf) != LY_SUCCESS) {
    .....
    }
    

    Then I output the ntf tree, and it turned out like this:

      <edit-config>
        <target>
          <running/>
        </target>
        <config>
    		<A xmlns='urn:ietf:params:xml:ns:yang:A'>
    		  <B>
    			<C>
    			  <C-type>YY</C-type>
    			</C>
    			<C>
    			  <C-type>XX</C-type>
    			</C>
    		  </C>
    		</A>
        </config>
      </edit-config>
    

    By the way, I found that the behavior of the lyplg_type_sort_enum interface is inconsistent with the behavior of other sort functions.
    LIBYANG_API_DEF int

    lyplg_type_sort_enum(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1,
            const struct lyd_value *val2)
    {
        if (val1->enum_item->value > val2->enum_item->value) {      // this the difference.
            return -1;
        } else if (val1->enum_item->value < val2->enum_item->value) {     // this the difference.
            return 1;
        } else {
            return 0;
        }
    }
    
    LIBYANG_API_DEF int
    lyplg_type_sort_int(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
    {
        switch (val1->realtype->basetype) {
        case LY_TYPE_INT8:
            if (val1->int8 < val2->int8) {            // this the difference.
                return -1;
            } else if (val1->int8 > val2->int8) {        // this the difference.
                return 1;
            } else {
                return 0;
            }
            break;
    ....
    
  5. michalvasko commented on Jan 26, 2026

    @michalvasko
    Member

    I found that the behavior of the lyplg_type_sort_enum interface is inconsistent with the behavior of other sort functions.

    So that may be the issue, was fixed in version 4.0.8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    is:questionIssue is actually a question.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions