The first issue with your query, is that the markdown you’re using are not producing correct headers as seen by Dataview. To see my point try doing this query in the file with the bookmarks:
```dataview
TABLE meta(item.section)
WHERE file = this.file
FLATTEN file.lists as item
WHERE item.Browser
```
This should display a table starting with something like:
And as you can see, it doesn’t list the “bookmark:: 2” as the header, but the semantically correct header of “Firefox bookmarks”.
To be able to sort your current structure into something resembling your wanted output, you’ll need to focus on the item with the bookmark
and then look into its children to pull out the wanted information from those.
Try playing around with the following query:
```dataview
TABLE item.bookmark, item.children.text, browser, url, name, category
WHERE file = this.file
FLATTEN file.lists as item
FLATTEN default(nonnull(item.children.Browser)[0], "") as browser
FLATTEN default(nonnull(item.children.Category)[0], "") as category
FLATTEN default(nonnull(item.children.URL)[0], "") as url
FLATTEN default(nonnull(item.children.Name)[0], "") as name
WHERE item.bookmark
SORT item.bookmark, browser
```
The item.children.text
is just for debug purposes, as well as the limitation of WHERE file = this.file
which focuses on the current file only. The monstrosity of this query is the FLATTEN
lines, which I can try to decipher for you:
FLATTEN ... as browser
– This will evaulate the expression, and store it intobrowser
readily available for use later on in the querydefault( ..., "")
– This function will use the value of the expression, and if that doesn’t hold a value, use the empty string as a result,""
. This ensures that if you don’t have that particular value in your sublist, the query won’t breaknonnull( ... )[0]
– After evaluation the expression in a list context, it removes any entries not having any value, and then it picks the first item (and hopefully only) item out of that list with the trailing[0]
item.children.Browser
– Using some Dataview magic, this will scan the items of the current item (which due to theWHERE
clause is the item with thebookmark
definition) for any variable calledBrowser
. In short pull out anyBrowser
field from the sub-list
So in a more natural language, it’ll scan the sub-lists for a given variable, forget about any items not having a Browser
field, and assign that value, if found, to another variable browser
. If not found, let browser
be the empty string.
The query above when run on your example provides something like:
Hopefully this’ll get you moving forward. But remember that your syntax of using header notation within a list isn’t treated as a header as such by Obsidian.