Forum How do I...?

Support for XML cross-references

gareth
I think I'm missing something but cannot seem to get XML xrefs working. Consider:
<toc-entry>
    <label>1.2.3</label>
    <title>Sample TOC entry</title>
    <nav-pointer rid="sec_1.2.3"/>
</toc-entry>

I need nav-pointer to output the page reference. So, within the CSS for nav-pointer, I'm using
target-counter(attr(rid), page)
but it doesn't resolve the page counter. If I update my @rid attribute to add the leading hash mark (e.g., rid="#sec_1.2.3") then it does work, as @rid is now a URL fragment.


Unfortunately, if I add the hash mark to the XML attributes, then the XML is invalid. I tried CSS variables but var() doesn't seem to work within target-counter, so I'm out of ideas. What is best practice please?
David J Prokopetz
If no other solution suggests itself, you could append a small Javascript when processing the XML file with Prince to tweak its contents into something Prince understands (in this case, to insert the hash mark into the rid attribute). Perhaps something like this:

let navPointers = document.querySelectorAll('nav-pointer');
for (let i = 0; i < navPointers.length; i++) {
    navPointers[i].setAttribute('rid', '#' + navPointers[i].getAttribute('rid'));
}


(If you're using Prince from the command line, an external Javascript file can be included using the --script argument.)
gareth
Thanks David, that is a great suggestion and pre-processing is something I'm already doing with these files with XSLT. The use of Javascript means I don't have to make the XML invalid prior to publishing.
I will see if anyone else has any tips or advice on best practice. I had assumed XML xref handling would be a core product capability, but this option works just fine.
mikeday
This should also work:
target-counter(attr(rid idref), page)

The idref attr type is a Prince-specific extension which will treat the attribute value as if it was an IDREF, essentially converting it to a URL by prepending the hash.
David J Prokopetz
As an FYI, Mike, the "idref" keyword for the attribute type doesn't seem to be mentioned in the current documentation. I just double-checked to make sure I'm not crazy, and it looks like it *was* mentioned in the docs up until version 11, but seems to have been (accidentally?) omitted from every version thereafter.
mikeday
Thanks, I need to check whether that was an accidental omission or an intentional deprecation!
gareth
Thank you both and the problem is now solved! These forums are amazing :)

... and good catch, David. A quick google over princexml.com shows only three references to the "idref" trick:
1. https://www.princexml.com/doc/11/pdf-output/
2. https://www.princexml.com/forum/topic/2209/cross-references-with-ambiguous-targets?p=1#14976
3. https://www.princexml.com/forum/topic/3673/internal-link-using-xml-attributes

What would have been helpful in my journey would be to have it as an example in one of the reference or user guides (or as a "tip and trick"). I guess it is mostly of use for XML inputs. The definition of attr() as it stands doesn't give quite enough of a clue how to make best use of this special feature.

BTW, I had stumbled across and tried attr(rid, url) but that didn't work, and I hadn't realised idref was an option.
csant
It looks like it quietly slipped out of the documentation. Thanks for bringing it up - it shall not only be re-instated, but it shall be better documented!