Controlling order of attributes with updates
Thursday, 10 February 2022 · 6 messages
JR
Jonathan Robie10 Feb 2022 00:16 #
Yes, I know that the order of attributes is insignificant. Except to some human beings who complain to me about the order of elements.
Is there any way for me to control the order of attributes in BaseX when I insert new attributes?
Jonathan
CG
Christian Grün10 Feb 2022 10:34 #
Hi Jonathan,
Quoted text · Jonathan Robie · 1 line
> Is there any way for me to control the order of attributes in BaseX when I insert new attributes?
If you evaluate the following XQuery expression in BaseX …
<a b='b' c='c'/>… you can be sure that the attributes will be placed in the original order. Please note that we cannot give a guarantee that this will stay that way forever, even though it’s unlikely to change.
If you have an existing element, you can reinsert all attributes in the order you want:
let $a := <a b='b' c='c'/>
return element { node-name($a) } {
$a/@*, attribute d { 'd' }, $a/node()
}How do you currently proceed?
Best,
Christian
HR
Hans-Juergen Rennau10 Feb 2022 12:34 #
[ Just a shout from the cheap seats in the gallery. In my experience, the order of attributes may have considerable esthetic value and may have impact on the acceptance of a program. The order therefore does deserve attention, in spite of its theoretical insignificance. Even more important than the order coming out of a literal constructor may be the order resulting from a dynamic constructor, that is, a sequence of attribute {...} {...}, because the developer can control that order dynamically, and all is well, provided BaseX plays along and retains the order. Yes, reordering is possible with the comma expression, but it would be nice to get away without that extra mile. ]
Am Donnerstag, 10. Februar 2022, 10:34:56 MEZ hat Christian Grün <christian.gruen at gmail.com> Folgendes geschrieben:
Hi Jonathan,
Quoted text · Christian Grün · 1 line
> Is there any way for me to control the order of attributes in BaseX when I insert new attributes?
If you evaluate the following XQuery expression in BaseX …
<a b='b' c='c'/>… you can be sure that the attributes will be placed in the original order. Please note that we cannot give a guarantee that this will stay that way forever, even though it’s unlikely to change.
If you have an existing element, you can reinsert all attributes in the order you want:
let $a := <a b='b' c='c'/>
return element { node-name($a) } {
$a/@*, attribute d { 'd' }, $a/node()
}How do you currently proceed?
Best,
Christian
JR
Quoted text · Christian Grün · 1 line
> How do you currently proceed?
I have two queries that add attributes to a morphology I am processing. Ideally, I would like each attribute to be added at the end of the attribute list, after any existing attributes.
The first adds an @after attribute if there is a space or punctuation after the token:
declare function local:segs($nodes)
{
if (head($nodes)[self::*:seg])
then concat(string(head($nodes)), local:segs(tail($nodes)))
else ()
};
declare variable $oshb := db:open("oshb-morphology");
for $w in $oshb//*:w
let $next := $w/following-sibling::*[1]
where $next
let $after :=
if ($next[self::*:w]) then " "
else if ($next[self::*:seg]) then local:segs($w/following-sibling::*)
else ""
return
insert node attribute after {$after} into $wThe second adds Book-Chapter-Verse-Word-Part numbering:
let $oshb := db:open("oshb-morphology")
for $verse in $oshb//*:verse
order by local:bcv($verse/@osisID)
for $w at $i in $verse/*[self::*:w or self::*:c]
for $p at $j in local:entities($w)
let $id := local:bcvwp($verse/@osisID, $i, $j)
return (
delete node $p/@n,
insert node attribute n {$id} into $p
)Quoted text · Christian Grün · 28 lines
On Thu, Feb 10, 2022 at 4:34 AM Christian Grün <christian.gruen at gmail.com> wrote: > Hi Jonathan, > > > Is there any way for me to control the order of attributes in BaseX when > I insert new attributes? > > If you evaluate the following XQuery expression in BaseX … > > <a b='b' c='c'/> > > … you can be sure that the attributes will be placed in the original > order. Please note that we cannot give a guarantee that this will stay > that way forever, even though it’s unlikely to change. > > If you have an existing element, you can reinsert all attributes in > the order you want: > > let $a := <a b='b' c='c'/> > return element { node-name($a) } { > $a/@*, attribute d { 'd' }, $a/node() > } > > How do you currently proceed? > > Best, > Christian >
JR
Attribute order matters even more when you have bidi and are using typical programming editors. Here's one problem I am facing - look at the @after attribute, as displayed in some editors:
Sublime doesn't handle bidi, so the element content, which is the word in question, is spelled backwards - but the @after attribute displays correctly precisely because it doesn't handle bidi:
[image: image.png]
But editors that typically do support bidi have real problems displaying this properly. In this example, the content of @after looks like a colon, but it is actually a sof passuq, a Hebrew character, and the character sequences involved display weirdly in many editors.
vi:
[image: image.png]
Emacs:
[image: image.png]
Adding an attribute that does not contain RTL text solves the display problem in many editors:
[image: image.png]
So attribute order matters more than usual in this setting ...
Jonathan
Quoted text · Hans-Juergen Rennau · 46 lines
On Thu, Feb 10, 2022 at 6:34 AM Hans-Juergen Rennau <hrennau at yahoo.de> wrote: > [ Just a shout from the cheap seats in the gallery. In my experience, the > order of attributes may have considerable esthetic value and may have > impact on the acceptance of a program. The order therefore does deserve > attention, in spite of its theoretical insignificance. Even more important > than the order coming out of a literal constructor may be the order > resulting from a dynamic constructor, that is, a sequence of attribute > {...} {...}, because the developer can control *that* order dynamically, > and all is well, provided BaseX plays along and retains the order. Yes, > reordering is possible with the comma expression, but it would be nice to > get away without that extra mile. ] > > Am Donnerstag, 10. Februar 2022, 10:34:56 MEZ hat Christian Grün < > christian.gruen at gmail.com> Folgendes geschrieben: > > > Hi Jonathan, > > > > Is there any way for me to control the order of attributes in BaseX when > I insert new attributes? > > > If you evaluate the following XQuery expression in BaseX … > > <a b='b' c='c'/> > > … you can be sure that the attributes will be placed in the original > order. Please note that we cannot give a guarantee that this will stay > that way forever, even though it’s unlikely to change. > > If you have an existing element, you can reinsert all attributes in > the order you want: > > let $a := <a b='b' c='c'/> > return element { node-name($a) } { > $a/@*, attribute d { 'd' }, $a/node() > } > > How do you currently proceed? > > Best, > Christian > >
CG
Christian Grün10 Feb 2022 16:11 #
Thanks for your code snippets. If you are using XQuery Update, the best solution is to delete all attributes and reinsert them:
[1]
return (
delete nodes $w/@*,
insert nodes ($w/@*, attribute after { $after }) into $p
)
[2]
return (
delete nodes $p/@*,
insert nodes ($p/@* except @p, attribute n { $id }) into $p
)If you know that the attribute already exists, you can simply replace its value:
[2]
replace value of node $p/@n with $id
Quoted text · Jonathan Robie · 79 lines
On Thu, Feb 10, 2022 at 2:26 PM Jonathan Robie <jonathan.robie at gmail.com> wrote: > Attribute order matters even more when you have bidi and are using typical > programming editors. Here's one problem I am facing - look at the @after > attribute, as displayed in some editors: > > Sublime doesn't handle bidi, so the element content, which is the word in > question, is spelled backwards - but the @after attribute displays > correctly precisely because it doesn't handle bidi: > > [image: image.png] > > But editors that typically do support bidi have real problems displaying > this properly. In this example, the content of @after looks like a colon, > but it is actually a sof passuq, a Hebrew character, and the character > sequences involved display weirdly in many editors. > > vi: > [image: image.png] > > Emacs: > [image: image.png] > > Adding an attribute that does not contain RTL text solves the display > problem in many editors: > > [image: image.png] > > So attribute order matters more than usual in this setting ... > > Jonathan > > On Thu, Feb 10, 2022 at 6:34 AM Hans-Juergen Rennau <hrennau at yahoo.de> > wrote: > >> [ Just a shout from the cheap seats in the gallery. In my experience, the >> order of attributes may have considerable esthetic value and may have >> impact on the acceptance of a program. The order therefore does deserve >> attention, in spite of its theoretical insignificance. Even more important >> than the order coming out of a literal constructor may be the order >> resulting from a dynamic constructor, that is, a sequence of attribute >> {...} {...}, because the developer can control *that* order dynamically, >> and all is well, provided BaseX plays along and retains the order. Yes, >> reordering is possible with the comma expression, but it would be nice to >> get away without that extra mile. ] >> >> Am Donnerstag, 10. Februar 2022, 10:34:56 MEZ hat Christian Grün < >> christian.gruen at gmail.com> Folgendes geschrieben: >> >> >> Hi Jonathan, >> >> >> > Is there any way for me to control the order of attributes in BaseX >> when I insert new attributes? >> >> >> If you evaluate the following XQuery expression in BaseX … >> >> <a b='b' c='c'/> >> >> … you can be sure that the attributes will be placed in the original >> order. Please note that we cannot give a guarantee that this will stay >> that way forever, even though it’s unlikely to change. >> >> If you have an existing element, you can reinsert all attributes in >> the order you want: >> >> let $a := <a b='b' c='c'/> >> return element { node-name($a) } { >> $a/@*, attribute d { 'd' }, $a/node() >> } >> >> How do you currently proceed? >> >> Best, >> Christian >> >>
Written for BaseX 9.6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery