问题
Here is the existing XML-source and XSLT-transformation code which restores all parent-child interconnetion chain. The algorithm does the correct work, but need to take into account new additional conditions; plus output "string" (or names) values have to take more formalized, proper form.
======= base source
<root>
<document ID-1="galaxyID" ID-2="NULL" ID-3="111" SHORTNAME="gal" NAME="Milky Way"/> <!-- this is parent's node -->
<document ID-1="starID" ID-2="galaxyID" ID-3="222" SHORTNAME="st" NAME="Sun"/> <!-- this is subparent -->
<document ID-1="planetID" ID-2="starID" ID-3="333" SHORTNAME="pl" NAME="Earth"/> <!-- this is subparent -->
<document ID-1="africaID" ID-2="planetID" ID-3="aaa" SHORTNAME="сont" NAME="Africa"/> <!-- child-1 -->
<document ID-1="australiaID" ID-2="planetID" ID-3="bbb" SHORTNAME="сont" NAME="Australia"/> <!-- child-2 -->
<document ID-1="eurasiaID" ID-2="planetID" ID-3="ccc" SHORTNAME="сont" NAME="Eurasia"/> <!-- child-3 -->
<document ID-1="antarcticaID" ID-2="planetID" ID-3="ddd" SHORTNAME="сont" NAME="Antarctica"/> <!-- child-4 -->
</root>
======== base xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="ref" match="document" use="@ID-1"/>
<xsl:template match="document">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('ref', @ID-2)" mode="att"/>
</xsl:copy>
</xsl:template>
<xsl:template match="document" mode="att">
<xsl:param name="pos" select="count(@*) + 1"/>
<xsl:attribute name="attr-{$pos}">
<xsl:value-of select="@NAME"/>
</xsl:attribute>
<xsl:apply-templates select="key('ref', @ID-2)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
======== base output
<?xml version="1.0" encoding="utf-16"?>
<root>
<document ID-1="galaxyID" ID-2="NULL" ID-3="111" SHORTNAME="gal" NAME="Milky Way" />
<document ID-1="starID" ID-2="galaxyID" ID-3="222" SHORTNAME="st" NAME="Sun" attr-6="Milky Way" />
<document ID-1="planetID" ID-2="starID" ID-3="333" SHORTNAME="pl" NAME="Earth" attr-6="Sun" attr-7="Milky Way" />
<document ID-1="africaID" ID-2="planetID" ID-3="aaa" SHORTNAME="сont" NAME="Africa" attr-6="Earth" attr-7="Sun" attr-8="Milky Way" />
<document ID-1="australiaID" ID-2="planetID" ID-3="bbb" SHORTNAME="сont" NAME="Australia" attr-6="Earth" attr-7="Sun" attr-8="Milky Way" />
<document ID-1="eurasiaID" ID-2="planetID" ID-3="ccc" SHORTNAME="сont" NAME="Eurasia" attr-6="Earth" attr-7="Sun" attr-8="Milky Way" />
<document ID-1="antarcticaID" ID-2="planetID" ID-3="ddd" SHORTNAME="сont" NAME="Antarctica" attr-6="Earth" attr-7="Sun" attr-8="Milky Way" />
</root>
https://xsltfiddle.liberty-development.net/ncntCSJ/3
interconnetion scheme
============================ NEW AIMS ============================
1- Additional condition within recursion
Along with each cycle add checking that each compared element has:
the attribute STATUS=0
and attribute ATTRIBUTE-NULL is null (here it simply means that there is no attribute ATTRIBUTE-NULL within the element, actualy)
2- String output correction
2.1 Name concatenation
The recursion make a coherent chain of entities, so their string explication - "Names" can be concatenated. There are 2 levels of concatenation:
a) concatenation within one level [SHORTNAME]+[.]+[NAME] (concatenation within one element).
<EXAMPLE SHORTNAME="pl" NAME="Earth"/> --->> <EXAMPLE FULLNAME="pl. Earth"/>
b) concatenation between levels
<EXAMPLE FULLNAME="gal. Milky Way, st. Sun, pl. Earth, сont. Eurasia"/> <!-- note additional commas and dots -->
2.2 Limited output attributes' nomenclature depending on hierarchy levels
In the existed XSLT-code transient attributes with "names" is formed randomly dynamic (counts the number of the attribute's position within the element). In the real situation, the numeric postfix may well grow to the third dozen. So to improve the situation it could be useful to implement a limited range of dynamically generated inbound attributes just tied to the number of hierarchy levels. Like:
<EXAMPLE LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="pl. Earth" LEVEL-4="сont. Eurasia"/>
2.3 RANK (an attribute)
RANK is a final check-point. All restored chains must be ordered by the RANK attribute (it may match with a native recursion, but sometimes not. Anyhow RANK attribute has higher priority. (this rule is also demonstrated in the assumed output).
====== TASK SOURCE
<root>
<document ID-1="galaxyID" ID-2="NULL" ID-3="111" SHORTNAME="gal" NAME="Milky Way" STATUS="0" RANK="1"/>
<document ID-1="starID" ID-2="galaxyID" ID-3="222" SHORTNAME="st" NAME="Sun" STATUS="0" RANK="3"/>
<document ID-1="planetID" ID-2="starID" ID-3="333" SHORTNAME="pl" NAME="Earth" STATUS="0" RANK="6"/>
<document ID-1="africaID" ID-2="planetID" ID-3="aaa" SHORTNAME="сont" NAME="Africa" STATUS="0" RANK="8"/>
<document ID-1="australiaID" ID-2="planetID" ID-3="bbb" SHORTNAME="сont" NAME="Australia" STATUS="0" RANK="8"/>
<document ID-1="eurasiaID" ID-2="planetID" ID-3="ccc" SHORTNAME="сont" NAME="Eurasia" STATUS="0" RANK="9"/>
<document ID-1="antarcticaID" ID-2="planetID" ID-3="ddd" SHORTNAME="сont" NAME="Antarctica" STATUS="0" RANK="5"/>
<!--note RANK! (higher than parent's "Earth" rank. So in the output they are switching )-->
<document ID-1="atlantisID" ID-2="planetID" ID-3="zzz" SHORTNAME="is" NAME="Atlantis" STATUS="2" NULL-ATTRIBUTE="some-value" RANK="8"/>
</root>
====== TASK'S ASSUMED OUTPUT
<!-- ORDER NOTE:- not "continent-planet-star-galaxy" but "galaxy-star-planet-continent" -->
<root>
<document ID-1="galaxyID" ID-2="NULL" ID-3="111" SHORTNAME="gal" NAME="Milky Way" STATUS="0" RANK="1"
FULLNAME="gal. Milky Way"
LEVEL-1="gal. Milky Way"/>
<document ID-1="starID" ID-2="galaxyID" ID-3="222" SHORTNAME="st" NAME="Sun" STATUS="0" RANK="3"
FULLNAME="gal. Milky Way, st. Sun"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun"/>
<document ID-1="planetID" ID-2="starID" ID-3="333" SHORTNAME="pl" NAME="Earth" STATUS="0" RANK="6"
FULLNAME="gal. Milky Way, st. Sun, pl. Earth"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="pl. Earth"/>
<document ID-1="africaID" ID-2="planetID" ID-3="aaa" SHORTNAME="сont" NAME="Africa" STATUS="0" RANK="8"
FULLNAME="gal. Milky Way, st. Sun, pl. Earth, cont. Africa"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="pl. Earth" LEVEL-4="cont. Africa"/>
<document ID-1="australiaID" ID-2="planetID" ID-3="bbb" SHORTNAME="сont" NAME="Australia" STATUS="0" RANK="8"
FULLNAME="gal. Milky Way, st. Sun, pl. Earth, cont. Australia"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="pl. Earth" LEVEL-4="cont. Australia"/>
<document ID-1="eurasiaID" ID-2="planetID" ID-3="ccc" SHORTNAME="сont" NAME="Eurasia" STATUS="0" RANK="9"
FULLNAME="gal. Milky Way, st. Sun, pl. Earth, cont. Eurasia"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="pl. Earth" LEVEL-4="cont. Eurasia"/>
<document ID-1="antarcticaID" ID-2="planetID" ID-3="ddd" SHORTNAME="сont" NAME="Antarctica" STATUS="0" RANK="5"
FULLNAME="gal. Milky Way, st. Sun, cont. Antarctica, pl. Earth"
LEVEL-1="gal. Milky Way" LEVEL-2="st. Sun" LEVEL-3="cont. Antarctica" LEVEL-4="pl. Earth"/>
<!--note! Earth and Antarctica switching because of RANK-->
<document ID-1="atlantisID" ID-2="planetID" ID-3="zzz" SHORTNAME="is" NAME="Atlantis" STATUS="2" NULL-ATTRIBUTE="some-value" RANK="8" />
<!-- nothing happens because of STATUS and NULL-ATTRIBUTE-->
</root>
the question is what XSLT code can be applied for that?
来源:https://stackoverflow.com/questions/59803035/adding-some-new-conditions-to-the-xslt-recursion