samsons17 -4 Posting Whiz in Training

I have this XML data which basically to add/minus/multiply the two numbers. And I have this Xquery function that suppose to convert this XML data into a readable string format.

For example, let say XML file has in this form :

<expr>
    <add> 
     <number>2</number>
     <number>3</number> 
    </add>
</expr>
<expr>
    <divide>
        <number>7</number>
        <times>
            <number>1</number>
            <number>6</number>
        </times>
    </divide>
</expr>

the Xquery function will be able to convert this into "2 + 3" and 7 / (1 * 6) respectively through the local:convertExpr function

Below is the sample of the Xquery that I am working right now :

Xquery File :

declare function local:convertExpr($expr) {
    (: function to convert XML into a readable string format :)

    let $number := data($expr[1])

    let $x := $number
    return $x
};

validate{<html>
    <head>
        <title>{/*/q:title/text()}</title>
        <script type="text/javascript" src="miniformvalidator.js"/>
    </head>
    <body>
        <h1>{/*/q:title/text()}</h1>
        <form>
            <ol>
            {
                let $exprs := /*/q:expr, 
                    $count := count($exprs)
                 for $i in (1 to $count)
                 let $expr := $exprs[$i]
                 return <li>{local:convertExpr($expr)}</li>
            }
            </ol>
        </form>

    </body>
</html>}

I am able to pull all the numbers within the tags right now, but I am not sure how I can connect these numbers to become one readable string.

Please help. Thanks! :)

Dani AI

Generated

A small, robust approach is to walk the XML tree recursively, map tag names to operator symbols and numeric precedence, and insert parentheses only when a child expression has lower precedence (or when right-hand children of non-associative ops need grouping). That produces readable infix like the examples showed: 2 + 3 and 7 / (1 * 6).

Try a recursive XQuery implementation like this:

declare function local:prec($n) {
  if (local-name($n) = 'number') then 100
  else if (local-name($n) = 'times' or local-name($n) = 'multiply') then 20
  else if (local-name($n) = 'divide' or local-name($n) = 'div') then 20
  else if (local-name($n) = 'add' or local-name($n) = 'plus') then 10
  else if (local-name($n) = 'minus' or local-name($n) = 'subtract') then 10
  else 0
};

declare function local:to-infix($e) {
  if (local-name($e) = 'number') then normalize-space(string($e))
  else
    let $op := local-name($e)
    let $sym := if ($op = 'add' or $op = 'plus') then ' + '
               else if ($op = 'times' or $op = 'multiply') then ' * '
               else if ($op = 'divide' or $op = 'div') then ' / '
               else if ($op = 'minus' or $op = 'subtract') then ' - '
               else ' '
    let $children := $e/*
    return string-join(
      for $i in 1 to count($children)
      let $c := $children[$i]
      let $s := local:to-infix($c)
      let $need := (local:prec($c) < local:prec($e))
                  or (
                    (local-name($e) = 'divide' or local-name($e) = 'minus' or local-name($e) = 'subtract')
                    and $i > 1
                    and local:prec($c) = local:prec($e)
                  )
      return if ($need) then concat('(', $s, ')') else $s
    , $sym)
};

Notes and tips:

  • Use local-name() so the code works even if your elements use a namespace prefix.
  • normalize-space() on number nodes avoids stray whitespace.
  • Parentheses rules above handle precedence and the common left-associative gotchas for - and /. If your input represents different associativity or has unary minus, adapt the rules.
  • Call local:to-infix($expr) where you previously used local:convertExpr($expr) to render each <expr>.

This pattern is easy to extend (add mod, pow, functions, etc.) and keeps output minimal and predictable.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.