user: Translate the below assembly code into C programming language:

```asm
<xml_parse_doc>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,%r15
  mov    %esi,%r12d
  mov    %rdx,%rbx
  mov    %rcx,%rbp
  mov    %r8,%r14
  lea    0x1(%rsi),%edi
  call   <xml_malloc@plt>
  mov    %rax,%r13
  mov    %r12d,%edx
  mov    %r15,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  movslq %r12d,%r12
  movb   $0x0,0x0(%r13,%r12,1)
  test   %rbx,%rbx
  je     L13
  test   %r14,%r14
  jne    L70
L13:
  test   %rbx,%rbx
  je     L73
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x4(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,%r15
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  lea    D1(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x5(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,0x8(%rsp)
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  lea    D69(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
L53:
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x5(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,(%rsp)
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  lea    D77(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
L30:
  mov    %r15,%rsi
  mov    %r13,%rdi
  call   <strstr@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L36
  mov    %r15,%rdi
  call   <strlen@plt>
  cltq
  add    %r12,%rax
  mov    (%rsp),%rsi
  mov    %rax,0x10(%rsp)
  mov    %rax,%rdi
  call   <strstr@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L37
  mov    %eax,%ecx
  sub    0x10(%rsp),%ecx
  mov    %ecx,0x1c(%rsp)
  mov    %r14,%rdx
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  call   <xml_new_element@plt>
  mov    %rax,%r12
  mov    %rax,%rdx
  mov    0x1c(%rsp),%esi
  mov    0x10(%rsp),%rdi
  call   <_xml_parse_doc@plt>
L37:
  mov    %r15,%rdi
  call   <xml_free@plt>
  mov    (%rsp),%rdi
  call   <xml_free@plt>
  mov    0x8(%rsp),%rdi
  call   <xml_free@plt>
  mov    %r13,%rdi
  call   <xml_free@plt>
  mov    %r12,%rax
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L70:
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    (%rax,%r12,2),%r12d
  mov    %r14,%rdi
  call   <strlen@plt>
  lea    0xe(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,%r15
  mov    %r14,%r9
  mov    %rbx,%r8
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  lea    D3(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    (%rax,%r12,2),%r12d
  mov    %r14,%rdi
  call   <strlen@plt>
  lea    0xf(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,0x8(%rsp)
  mov    %r14,%r9
  mov    %rbx,%r8
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  lea    D49(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  jmp    L53
L73:
  test   %r14,%r14
  je     L108
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %r14,%rdi
  call   <strlen@plt>
  lea    0xc(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,%r15
  mov    %r14,%rcx
  mov    %rbp,%rdx
  lea    D79(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    %eax,%r12d
  mov    %r14,%rdi
  call   <strlen@plt>
  lea    0xd(%r12,%rax,1),%edi
  call   <xml_malloc@plt>
  mov    %rax,0x8(%rsp)
  mov    %r14,%rcx
  mov    %rbp,%rdx
  lea    D32(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
L89:
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x4(%rax),%edi
  call   <xml_malloc@plt>
  mov    %rax,(%rsp)
  mov    %rbp,%rdx
  lea    D7(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  jmp    L30
L108:
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x3(%rax),%edi
  call   <xml_malloc@plt>
  mov    %rax,%r15
  mov    %rbp,%rdx
  lea    D65(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x4(%rax),%edi
  call   <xml_malloc@plt>
  mov    %rax,0x8(%rsp)
  mov    %rbp,%rdx
  lea    D64(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  jmp    L89
L36:
  mov    0x8(%rsp),%rsi
  mov    %r13,%rdi
  call   <strstr@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L37
  mov    %r14,%rdx
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  call   <xml_new_element@plt>
  mov    %rax,%r12
  jmp    L37
```

tool_calls: name: retrieve_data
arguments: data_tag: D1
datatype: string
name: retrieve_data
arguments: data_tag: D69
datatype: string
name: retrieve_data
arguments: data_tag: D77
datatype: string
name: retrieve_data
arguments: data_tag: D3
datatype: string
name: retrieve_data
arguments: data_tag: D49
datatype: string
name: retrieve_data
arguments: data_tag: D79
datatype: string
name: retrieve_data
arguments: data_tag: D32
datatype: string
name: retrieve_data
arguments: data_tag: D7
datatype: string
name: retrieve_data
arguments: data_tag: D65
datatype: string
name: retrieve_data
arguments: data_tag: D64
datatype: string

tool: D1: <%s:%s>

tool: D69: <%s:%s/>

tool: D77: </%s:%s>

tool: D3: <%s:%s xmlns:%s="%s">

tool: D49: <%s:%s xmlns:%s="%s"/>

tool: D79: <%s xmlns="%s">

tool: D32: <%s xmlns="%s"/>

tool: D7: </%s>

tool: D65: <%s>

tool: D64: <%s/>

assistant: ```c
struct xml_node *xml_parse_doc(char *doc_buf, int doc_len, char *doc_prefix, char *doc_name, char *doc_uri) {
  struct xml_node *root = NULL;
  char *xml_buf, *start_tag, *end_tag, *empty_tag, *front, *rear;
  xml_buf = (char *)xml_malloc(doc_len + 1);
  memcpy(xml_buf, doc_buf, doc_len);
  xml_buf[doc_len] = '\0';
  if (doc_prefix && doc_uri) {
    start_tag = (char *)xml_malloc(2 * strlen(doc_prefix) + strlen(doc_name) + strlen(doc_uri) + 14);
    sprintf(start_tag, "<%s:%s xmlns:%s=\"%s\">", doc_prefix, doc_name, doc_prefix, doc_uri);
    empty_tag = (char *)xml_malloc(2 * strlen(doc_prefix) + strlen(doc_name) + strlen(doc_uri) + 15);
    sprintf(empty_tag, "<%s:%s xmlns:%s=\"%s\"/>", doc_prefix, doc_name, doc_prefix, doc_uri);
  } else if (doc_prefix) {
    start_tag = (char *)xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 4);
    sprintf(start_tag, "<%s:%s>", doc_prefix, doc_name);
    empty_tag = (char *)xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 5);
    sprintf(empty_tag, "<%s:%s/>", doc_prefix, doc_name);
  } else if (doc_uri) {
    start_tag = (char *)xml_malloc(strlen(doc_name) + strlen(doc_uri) + 12);
    sprintf(start_tag, "<%s xmlns=\"%s\">", doc_name, doc_uri);
    empty_tag = (char *)xml_malloc(strlen(doc_name) + strlen(doc_uri) + 13);
    sprintf(empty_tag, "<%s xmlns=\"%s\"/>", doc_name, doc_uri);
  } else {
    start_tag = (char *)xml_malloc(strlen(doc_name) + 3);
    sprintf(start_tag, "<%s>", doc_name);
    empty_tag = (char *)xml_malloc(strlen(doc_name) + 4);
    sprintf(empty_tag, "<%s/>", doc_name);
  }
  if (doc_prefix) {
    end_tag = (char *)xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 5);
    sprintf(end_tag, "</%s:%s>", doc_prefix, doc_name);
  } else {
    end_tag = (char *)xml_malloc(strlen(doc_name) + 4);
    sprintf(end_tag, "</%s>", doc_name);
  }
  if ((front = strstr(xml_buf, start_tag)) != NULL) {
    front += strlen(start_tag);
    if ((rear = strstr(front, end_tag)) != NULL) {
      int xml_len = rear - front;
      root = xml_new_element(doc_prefix, doc_name, doc_uri);
      _xml_parse_doc(front, xml_len, root);
    }
  } else if ((front = strstr(xml_buf, empty_tag)) != NULL) {
    root = xml_new_element(doc_prefix, doc_name, doc_uri);
  }
  xml_free(start_tag);
  xml_free(end_tag);
  xml_free(empty_tag);
  xml_free(xml_buf);
  return root;
}
```