BNF is just a notation for describing a formal language. Although there are many slight variations of BNF in use, BNF is generally used to describe very precisely the exact syntactically legal sentences (that is, sequences symbols) that belong to a formal language.
Some languages are simple, for example the language that is any sequence of one or more 'A'.
A, AA, AAA, AAAA and so forth are all valid sentences in this language. This is a particularly simple language, but it could be described in BNF:
<S> ::= A | <S> A
This language could also be specified as { A^n | n >= 1 } using a set notation or as a regular expression like A+
A slightly more complex language is the language of all sentences made up of a sequence of A and B in any order followed by a sequence of C exactly twice as long as the A's and B's together:
<S> ::= <X>CC | <X><S>CC
<X> ::= A | B
Legal sentences look like: ACC, AACCCC, ABCCCC, BABCCCCCC, etc. Such a language can't be described by classical regular expressions, but can be described by the
context-free grammar expressed in BNF above.
There are alternatives and generalizations of BNF notations. Wirth used railroad diagrams to describe the syntax of PASCAL in the Pascal Report describing his language. This are more visual, but not more powerful.
BNF might be a pain, but there is generally no simple way to express complex syntax requirements for programming languages. BNF isn't used to solve the same problem being addressed by XML or JSON which are methods to encode data.