[xsl] How can I match some elements with cross-referencing?

Subject: [xsl] How can I match some elements with cross-referencing?
From: "Richard Kerry richard.kerry@xxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 16 Aug 2022 11:09:17 -0000
I am putting together an XSL stylesheet to convert the format of some XML
files [1].  I have a situation where I think I need some sort of
cross-referencing within the file for setting the template matches, but I
don't know how I might achieve that.
By that I mean that there are elements, lets call them type A, which use a
regular expression in their match specs, and when found it is also necessary
to find some related elements, type B, and rewrite them (or delete them).
I would appreciate some advice on what sort of method to use for this.

I think I can see three ways I might approach this.

  1.  On finding the type A element, its action includes finding the B element
and rewriting it.  This ties all the processing to one template match.
  2.  Two separate templates.  One matches elements A and processes them.  The
other matches elements of type B and includes some kind of look-up of any
corresponding type A element.
  3.  Extra passes.  First pass to extract a list of names, and second pass to
use that in the match spec, if possible.

I'm not sure whether the first of these is even possible.  It includes one
template match of an element rewriting another element entirely.  That's not
XSL's usual model and I don't think it can be done, can it?

If the second option is the way to go, how should I go about defining the B
element match to include the "cross reference", ie the search to establish
whether there is a corresponding A  element?
There is not a 1:1 correspondence between the two types.  Not all B elements
have a corresponding A element.

So, to make it more concrete, let's say we have some A elements like this:

<A name="n1.u">Contents of A[n1]</A>
<A name="n2.u">Contents of A[n2]</A>
<A name="n3.u">Contents of A[n3]</A>

And some B like this:

<B reference="n1.u">Contents of B[n1]</B>
<B reference="n2.u">Contents of B[n2]</B>
<B reference="n3.u">Contents of B[n3]</B>

I can match The A elements using a regex match like "A[matches(@name,
'(.+).u')]".  Then use analyze-string and regex-group to extract the useful
information from the @name attribute.  I know that works as I've done
something similar before.
For each match I think it would be straightforward to use this extracted
information to look up data from a corresponding B element.  Something like
B[@reference == $whatever].  But I don't think I can rewrite B using this
method , can I?

So the second option would seem to be to have a second template which matches
with some kind of cross-reference in the match spec.  Something like
"B[cross-reference-match(A, @name, @reference)])".  To mean a B element where
there is an A element where A/@name is the same as B/@reference.  That seems
to be more in the spirit of XSL, but I don't know whether it is possible, and
if so what keywords or techniques to look for.

To put it another way, I would be looking to match:
A B element where its @reference matches the @name of any A element.


The third method would be to use the A match to build a list of keywords, then
build a separate B match using them.  I'm not quite sure how I would go about
that, and it also doesn't seem particularly like a conventional XSL method.


I hope someone can advise how I should best go about doing this.  I am using
Saxon (HE) so I believe I have XSL 2 or 3 available to me.

Regards,
Richard.


[1]
It's actually conversion of some projects from Qt 3 to Qt 4, in a Windows
environment using Visual Studio.  The system provides utilities to convert the
user interface files (.ui), but there is then some editing required for the
project files, which are XML.

An A element starts
    <CustomBuild Include="longtextdialog.ui">
For Qt 3 the rest of this element causes three files to be generated, but for
Qt 4 only one.

The corresponding B elements are
    <ClCompile Include="longtextdialog.cpp" />
Or
    <ClCompile Include="moc_longtextdialog.cpp" />
Or
    <ClInclude Include="longtextdialog.h" />

So these need matching and rewriting.  There are many other <ClInclude
Include="*.*" /> elements which don't need processing (ie which just need
copying to the output), hence the requirement to match only those with a
matching CustomBuild.




[Atos logo]

Richard Kerry
BNCS Engineer, SI SOL Telco & Media Vertical Practice
M: +44 (0)7812 325518
2nd Floor, MidCity Place, 71 High Holborn, London, WC1V 6EA
richard.kerry@xxxxxxxx<https://eur01.safelinks.protection.outlook.com/?url=ht
tps%3A%2F%2Fwebmail.siemens-it-solutions.com%2Fowa%2Fredir.aspx%3FC%3D9fb20d0
19e3e4cb99344d708709a3177%26URL%3Dmailto%253arichard.kerry%2540atos.net&data=
02%7C01%7Crichard.kerry%40atos.net%7C45cacbfc4f744ca0ca7f08d7f64a0a6d%7C33440
fc6b7c7412cbb730e70b0198d5a%7C0%7C0%7C637248670177930650&sdata=hTD7XY8vYsCmdZ
s6%2FWrFltAPrpaZ4QFZLMrxvVjie2k%3D&reserved=0>

[demime 1.01d removed an attachment of type image/png which had a name of image001.png]

Current Thread