Fix, (see also [S. Chazelas' answer][1] for background), with sensible output:

    #!/bin/bash
    IN="One-XX-X-17.0.0"
    IFS='-' read -r -a ADDR <<< "$IN"
    for i in "${ADDR[@]}"; do
        if [ "$i" = "${i//.}" ] ; then 
            echo "Element:$i" 
            continue
        fi
        # split 17.0.0 into NUM
        IFS='.' read -a array <<< "$i"
        for element in "${array[@]}" ; do
            echo "Num:$element"
        done
    done

Output:

    Element:One
    Element:XX
    Element:X
    Num:17
    Num:0
    Num:0

---

Notes:

 * It's better to put the conditional *2nd* loop *in* the *1st* loop.  

 * `bash` pattern substitution (`"${i//.}"`) is used check if there's a `.` in an element.  (A `case` statement might be simpler, albeit less similar to the *OP*'s code.)

 * `read`ing `$array` by inputting `<<< "${ADDR[3]}"` is less general than `<<< "$i"`.  It avoids needing to know *which* element has the `.`s.

 * The code assumes that printing "*Element:17.0.0*" is unintentional. 
   If That behavior *is* intended, replace the main loop with:
   
        for i in "${ADDR[@]}"; do
           echo "Element:$i" 
           if [ "$i" != "${i//.}" ] ; then 
           # split 17.0.0 into NUM
               IFS='.' read -a array <<< "$i"
               for element in "${array[@]}" ; do
                   echo "Num:$element"
               done
           fi
        done

  [1]: https://unix.stackexchange.com/a/397208/165517