/ vs // in general
Both child (/) and descendant-or-self (//) are axes in XPath.
/ is short for /child::node()/.
Use / to select a node's immediate children.
// is short for /descendant-or-self::node()/.
Use // to select
a node, its children, its grandchildren, and so on
recursively.
/ vs // with preceding-sibling::*
Your specific question asks about the difference between //preceding-sibling::* and /preceding-sibling::*.
Since your data is offsite and complex, let's consider instead this present and simpler XML:
<r>
<a/>
<b>
<c/>
<d/>
</b>
</r>
For this XML,
/r/preceding-sibling::* selects nothing because r has no
preceding siblings.
/r//preceding-sibling::* selects the preceding siblings elements of
all of the descendant or self nodes of r. That is, a, b, c and d.
(Remember, /r//preceding-sibling::* is short for /descendant-or-self::node()/preceding-sibling::*, not /descendant-or-self::*/preceding-sibling::*) Note that even though b and d are predecessor siblings to no elements, they are predecessor siblings to text nodes because the above XML has whitespace after b and d. If all whitespace were removed, then only a and c would be selected.
/r/descendant::*/preceding-sibling::* selects the preceding sibling elements of all descendant elements of r. That is, a and c. Note that b and d are not selected because they are not preceding sibling elements to any descendant elements of r -- unlike the previous example, text nodes do not qualify.