ref #7745 fix bug in queries with subtree, some first test and cleanup
authorAndreas Müller <a.mueller@bgbm.org>
Wed, 12 Sep 2018 21:01:40 +0000 (23:01 +0200)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 12 Sep 2018 21:01:40 +0000 (23:01 +0200)
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImpl.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.xml

index b07294ef67d3472de40d1f226e9865afe510d482..32291b2cf710ffe34a9388c36c523e8f8fc1ab02 100755 (executable)
@@ -1449,13 +1449,16 @@ public class TaxonDaoHibernateImpl
                 boolean includeUnpublished, Classification classification, TaxonNode subtree,
                 Set<NamedArea> areasExpanded, MatchMode matchMode, String searchField){
 
+
         boolean doAreaRestriction = areasExpanded.size() > 0;
+        boolean hasTaxonNodeFilter = classification != null || subtree != null;
+
         String doAreaRestrictionSubSelect =
                      " SELECT %s.id "
                    + " FROM Distribution e "
                    + "    JOIN e.inDescription d "
                    + "    JOIN d.taxon t " +
-                (classification != null ? " JOIN t.taxonNodes AS tn " : " ");
+                (hasTaxonNodeFilter ? " JOIN t.taxonNodes AS tn " : " ");
 
         String doAreaRestrictionConceptRelationSubSelect =
                    "SELECT %s.id "
@@ -1465,7 +1468,7 @@ public class TaxonDaoHibernateImpl
 
         String doTaxonSubSelect =
                      " SELECT %s.id "
-                   + " FROM Taxon t " + (classification != null ? " "
+                   + " FROM Taxon t " + (hasTaxonNodeFilter ? " "
                            + " JOIN t.taxonNodes AS tn " : " ");
 
         String doTaxonMisappliedNameSubSelect =
@@ -1481,7 +1484,7 @@ public class TaxonDaoHibernateImpl
         String doConceptRelationJoin =
                    " LEFT JOIN t.relationsFromThisTaxon AS rft " +
                    " LEFT JOIN rft.relatedTo AS rt " +
-                      (classification != null ? " LEFT JOIN rt.taxonNodes AS tn2 " : " ") +
+                      (hasTaxonNodeFilter ? " LEFT JOIN rt.taxonNodes AS tn2 " : " ") +
                    " LEFT JOIN rt.name AS n2" +
                    " LEFT JOIN rft.type as rtype";
 
@@ -1509,7 +1512,7 @@ public class TaxonDaoHibernateImpl
         String conceptSelect = null;
         String commonNameSubselect = null;
 
-        if(classification != null || subtree != null){
+        if(hasTaxonNodeFilter){
             if (!doConceptRelations){
                 if(doAreaRestriction){
                     taxonSubselect = String.format(doAreaRestrictionSubSelect, "t") + doTaxonNameJoin +
index 351fd0d2f52c0e18bf90b7d9c62de2f355c308b7..274e2800b4f6fd919b3da0c102ec2289ad5730a6 100644 (file)
@@ -57,6 +57,7 @@ import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
 import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
 import eu.etaxonomy.cdm.persistence.query.GroupByCount;
 import eu.etaxonomy.cdm.persistence.query.GroupByDate;
@@ -77,6 +78,9 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
     @SpringBeanByType
     private ITaxonDao taxonDao;
 
+    @SpringBeanByType
+    private ITaxonNodeDao taxonNodeDao;
+
     @SpringBeanByType
     private IClassificationDao classificationDao;
 
@@ -86,16 +90,19 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
     @SpringBeanByType
     private IDefinedTermDao definedTermDao;
 
-    private UUID uuid;
-    private UUID sphingidae;
-    private UUID acherontia;
-    private UUID rethera;
-    private UUID retheraSecCdmtest;
-    private UUID atroposAgassiz; // a Synonym
-    private UUID atroposOken;  // a Synonym
-    private UUID atroposLeach; // a Synonym
-    private UUID acherontiaLachesis;
-    private UUID aus;
+    private UUID uuid = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
+    private UUID sphingidae = UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9");
+    private UUID acherontia = UUID.fromString("c5cc8674-4242-49a4-aada-72d63194f5fa");
+    private UUID rethera = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
+    private UUID retheraSecCdmtest = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
+    private UUID atroposAgassiz = UUID.fromString("d75b2e3d-7394-4ada-b6a5-93175b8751c1"); // a Synonym
+    private UUID atroposOken = UUID.fromString("6bfedf25-6dbc-4d5c-9d56-84f9052f3b2a");  // a Synonym
+    private UUID atroposLeach = UUID.fromString("3da4ab34-6c50-4586-801e-732615899b07"); // a Synonym
+    private UUID acherontiaLachesis = UUID.fromString("b04cc9cb-2b4a-4cc4-a94a-3c93a2158b06");
+    private UUID aus = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
+
+    private UUID UUID_ACHERONTIA_NODE = UUID.fromString("56b10cf0-9522-407e-9f90-0c2dba263c94");
+    private UUID UUID_CLASSIFICATION2 = UUID.fromString("a71467a6-74dc-4148-9530-484628a5ab0e");
 
     private AuditEvent previousAuditEvent;
     private AuditEvent mostRecentAuditEvent;
@@ -128,16 +135,6 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
     @Before
     public void setUp() {
 
-        uuid = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
-        sphingidae = UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9");
-        acherontia = UUID.fromString("c5cc8674-4242-49a4-aada-72d63194f5fa");
-        acherontiaLachesis = UUID.fromString("b04cc9cb-2b4a-4cc4-a94a-3c93a2158b06");
-        atroposAgassiz = UUID.fromString("d75b2e3d-7394-4ada-b6a5-93175b8751c1");
-        atroposOken = UUID.fromString("6bfedf25-6dbc-4d5c-9d56-84f9052f3b2a");
-        atroposLeach =  UUID.fromString("3da4ab34-6c50-4586-801e-732615899b07");
-        rethera = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
-        retheraSecCdmtest = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
-        aus = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
 
         previousAuditEvent = new AuditEvent();
         previousAuditEvent.setRevisionNumber(1025);
@@ -472,41 +469,40 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
         Synonym synAtroposAgassiz = (Synonym)taxonDao.findByUuid(atroposAgassiz);
         Taxon taxonRethera = (Taxon)taxonDao.findByUuid(rethera);
         taxonRethera.addSynonym(synAtroposAgassiz, SynonymType.SYNONYM_OF());
-        logger.warn("addSynonym(..)");
+        //logger.warn("addSynonym(..)");
         this.taxonDao.clear();
         Synonym synAtroposLeach = (Synonym)taxonDao.findByUuid(atroposLeach);
         Taxon taxonRetheraSecCdmtest = (Taxon)taxonDao.findByUuid(retheraSecCdmtest);
         taxonRetheraSecCdmtest.addSynonym(synAtroposLeach, SynonymType.SYNONYM_OF());
         this.taxonDao.clear();
+
         // 1. searching for a taxon (Rethera)
         //long numberOfTaxa = taxonDao.countTaxaByName(Taxon.class, "Rethera", null, MatchMode.BEGINNING, namedAreas);
 
         @SuppressWarnings("rawtypes")
-        List<TaxonBase> results = taxonDao.findByNameTitleCache(true, false, includeUnpublished, "Rethera Rothschild & Jordan, 1903", null, subtree, MatchMode.EXACT, namedAreas,
+        List<TaxonBase> results = taxonDao.findByNameTitleCache(doTaxa, noSynonyms, includeUnpublished, "Rethera Rothschild & Jordan, 1903", null, subtree, MatchMode.EXACT, namedAreas,
                 null, null, null, null);
         assertNotNull("getTaxaByName should return a List", results);
         assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
 
         // 2. searching for a taxon (Rethera) contained in a specific classification
-        results = taxonDao.findByNameTitleCache(true, false, includeUnpublished, "Rethera Rothschild & Jordan, 1903", classification, subtree, MatchMode.EXACT, namedAreas,
+        results = taxonDao.findByNameTitleCache(doTaxa, noSynonyms, includeUnpublished, "Rethera Rothschild & Jordan, 1903", classification, subtree, MatchMode.EXACT, namedAreas,
                 null, null, null, null);
         assertNotNull("getTaxaByName should return a List", results);
         assertTrue("expected to find one taxon but found "+results.size(), results.size() == 1);
 
-
         // 3. searching for Synonyms
-        results = taxonDao.findByNameTitleCache(false, true, includeUnpublished, "*Atropo", null, subtree, MatchMode.ANYWHERE, null,
+        results = taxonDao.findByNameTitleCache(noTaxa, doSynonyms, includeUnpublished, "*Atropo", null, subtree, MatchMode.ANYWHERE, null,
                 null, null, null, null);
         assertNotNull("getTaxaByName should return a List", results);
         assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
 
         // 4. searching for Synonyms
-        results = taxonDao.findByNameTitleCache(false, true, includeUnpublished, "Atropo", null, subtree, MatchMode.BEGINNING, null,
+        results = taxonDao.findByNameTitleCache(noTaxa, doSynonyms, includeUnpublished, "Atropo", null, subtree, MatchMode.BEGINNING, null,
                 null, null, null, null);
         assertNotNull("getTaxaByName should return a List", results);
         assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
 
-
         // 5. searching for a Synonyms and Taxa
         //   attache a synonym first
         Synonym syn = (Synonym)taxonDao.findByUuid(this.atroposLeach);
@@ -514,7 +510,7 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
         tax.addSynonym(syn, SynonymType.HETEROTYPIC_SYNONYM_OF());
 
         taxonDao.save(tax);
-        results = taxonDao.findByNameTitleCache(true, true, includeUnpublished, "A", null, subtree, MatchMode.BEGINNING, namedAreas,
+        results = taxonDao.findByNameTitleCache(doTaxa, doSynonyms, includeUnpublished, "A", null, subtree, MatchMode.BEGINNING, namedAreas,
                 null, null, null, null);
         assertNotNull("getTaxaByName should return a List", results);
         assertTrue("expected to find 8 taxa but found "+results.size(), results.size() == 8);
@@ -597,20 +593,48 @@ public class TaxonDaoHibernateImplTest extends CdmTransactionalIntegrationTest {
     @DataSet
     public void testCountTaxaByName() {
         TaxonNode subtree = null;
-        long numberOfTaxa = taxonDao.countTaxaByName(true, false, false, false,false, "A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        Classification classification= null;
+        long numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames,false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
         assertEquals(5, numberOfTaxa);
-        numberOfTaxa = taxonDao.countTaxaByName(true, false, false, false, false,"Smerinthus kindermannii", null, subtree, MatchMode.EXACT, null, includeUnpublished);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Sphingidae, Smerinthus, Smerinthus kindermannii and Sphingonaepiopsis expected", 4, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
         assertEquals(1, numberOfTaxa);
-        numberOfTaxa = taxonDao.countTaxaByName(false, true, false, false, false,"A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
         assertEquals(2, numberOfTaxa);
-        numberOfTaxa = taxonDao.countTaxaByName(true, true, false, false, false,"A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
         assertEquals(7, numberOfTaxa);
-        numberOfTaxa = taxonDao.countTaxaByName(true, true, false, false,false, "Aasfwerfwf fffe", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals(0, numberOfTaxa);
+
+        subtree = taxonNodeDao.findByUuid(UUID_ACHERONTIA_NODE);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Acherontia and 2 A. species expected", 3, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("", 0, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
+        assertEquals("Smerinthus is not in subtree", 0, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Atropos Agassiz and Atropos Oken expected as Synonyms", 2, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("The above accepted and synonyms expected", 5, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals(0, numberOfTaxa);
+
+        classification = classificationDao.findByUuid(UUID_CLASSIFICATION2);
+        subtree = null;
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Acherontia and 2 A. species expected", 3, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Sphingidae expected", 1, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
+        assertEquals("Smerinthus is not in subtree", 0, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("Atropos Agassiz and Atropos Oken expected as Synonyms", 2, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
+        assertEquals("The above accepted and synonyms expected", 5, numberOfTaxa);
+        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
         assertEquals(0, numberOfTaxa);
-//     FIXME implement test for search in specific classification
-//             Reference reference = referenceDao.findByUuid(UUID.fromString("596b1325-be50-4b0a-9aa2-3ecd610215f2"));
-//             numberOfTaxa = taxonDao.countTaxaByName("A*", MatchMode.BEGINNING, SelectMode.ALL, null, null);
-//             assertEquals(numberOfTaxa, 2);
     }
 
     @Test
index 92eef8a674e658b1b8663e340a0b4f15102a29bc..e31deefd2f63460aae80e2a80b9f8a7c137a5b93 100644 (file)
   <REFERENCE  ID="1" CREATED="2008-12-10 09:56:07.0" UUID="596b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="Lorem ipsum" PROTECTEDTITLECACHE="true" PROTECTEDABBREVTITLECACHE="false" ABBREVTITLECACHE="Sp. Pl." ABBREVTITLE="Sp. Pl." NOMENCLATURALLYRELEVANT="false" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1"/>\r
   <REFERENCE  ID="2" CREATED="2008-12-10 09:56:07.0" UUID="ad4322b7-4b05-48af-be70-f113e46c545e" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="cate-sphingidae.org" PROTECTEDTITLECACHE="true" PROTECTEDABBREVTITLECACHE="false" ABBREVTITLECACHE="Sp. Pl." ABBREVTITLE="Sp. Pl." NOMENCLATURALLYRELEVANT="false" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1"/>\r
   <REFERENCE  ID="3" CREATED="2008-12-10 09:56:07.0" UUID="3eea6f96-0682-4025-8cdd-aaaf7c915ae2" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="cate-araceae.org" PROTECTEDTITLECACHE="true" PROTECTEDABBREVTITLECACHE="false" ABBREVTITLECACHE="Sp. Pl." ABBREVTITLE="Sp. Pl." NOMENCLATURALLYRELEVANT="false" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1"/>\r
+  <CLASSIFICATION ID="5000" CREATED="2015-06-18 09:36:39.0" UUID="2a5ceebb-4830-4524-b330-78461bf8cb6b" PROTECTEDTITLECACHE="true" TITLECACHE="Classification 1" ROOTNODE_ID="5000"/>\r
+  <CLASSIFICATION ID="5001" CREATED="2015-06-18 09:36:39.0" UUID="a71467a6-74dc-4148-9530-484628a5ab0e" PROTECTEDTITLECACHE="true" TITLECACHE="Classification 2" ROOTNODE_ID="5001"/>\r
+  <TAXONNODE ID="5000" CREATED="2015-06-18 09:36:39.0" UUID="75202d4e-b2aa-4343-8b78-340a52d15c40" SORTINDEX="-1" TREEINDEX="#t5000#5000#"      COUNTCHILDREN="3" TAXON_ID="[null]" EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5000" PARENT_ID="[null]"/>\r
+  <TAXONNODE ID="5002" CREATED="2015-06-18 09:36:39.0" UUID="6b76c838-bd8f-43f9-8fa9-077cd222a9b2" SORTINDEX="0"  TREEINDEX="#t5000#5000#5002#" COUNTCHILDREN="0" TAXON_ID="1"   EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5000" PARENT_ID="5000"/>\r
+  <TAXONNODE ID="5004" CREATED="2015-06-18 09:36:39.0" UUID="ebbae10f-d179-4a08-9939-9fed0a7f1433" SORTINDEX="2"  TREEINDEX="#t5000#5000#5004#" COUNTCHILDREN="0" TAXON_ID="5002"   EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5000" PARENT_ID="5000"/>\r
+  <TAXONNODE ID="5001" CREATED="2015-06-18 09:36:39.0" UUID="7b95a2a6-2c6e-4b8e-a91a-7a1d995490f9" SORTINDEX="-1" TREEINDEX="#t5001#5001#"                COUNTCHILDREN="1" TAXON_ID="[null]" EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5001" PARENT_ID="[null]"/>\r
+  <TAXONNODE ID="5007" CREATED="2015-06-18 09:36:40.0" UUID="bcdf945f-1f02-423e-883d-fe89e0af93e4" SORTINDEX="0"  TREEINDEX="#t5001#5001#5007#"           COUNTCHILDREN="1" TAXON_ID="3"      EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5001" PARENT_ID="5001"/>\r
+  <TAXONNODE ID="5006" CREATED="2015-06-18 09:36:40.0" UUID="56b10cf0-9522-407e-9f90-0c2dba263c94" SORTINDEX="0"  TREEINDEX="#t5001#5001#5007#5006#"      COUNTCHILDREN="2" TAXON_ID="15"     EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5001" PARENT_ID="5007"/>\r
+  <TAXONNODE ID="5005" CREATED="2015-06-18 09:36:40.0" UUID="ba290371-a72b-43bf-a913-8a03c79755c7" SORTINDEX="0"  TREEINDEX="#t5001#5001#5007#5006#5005#" COUNTCHILDREN="0" TAXON_ID="35"     EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5001" PARENT_ID="5006"/>\r
+  <TAXONNODE ID="5008" CREATED="2015-06-18 09:36:40.0" UUID="80150ae0-e1e6-42a4-b224-21e099756c3d" SORTINDEX="1"  TREEINDEX="#t5001#5001#5007#5006#5008#" COUNTCHILDREN="0" TAXON_ID="36"     EXCLUDED="FALSE" UNPLACED="FALSE" CLASSIFICATION_ID="5001" PARENT_ID="5006"/>\r
+  \r
+  \r
   <TAXONBASE DTYPE="Taxon" ID="1" SEC_ID="1" CREATED="2008-01-10 09:56:07.0" UUID="496b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="Aus sec. ???" PROTECTEDTITLECACHE="true" TAXONSTATUSUNKNOWN="false"  PUBLISH="true" DOUBTFUL="false" USENAMECACHE="false" NAME_ID="1" />\r
   <TAXONBASE DTYPE="Taxon" ID="3" SEC_ID="2" CREATED="2008-01-12 09:56:07.0" UUID="54e767ee-894e-4540-a758-f906ecb4e2d9" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="Sphingidae Linnaeus, 1758 sec. cate-sphingidae.org" PROTECTEDTITLECACHE="true" TAXONSTATUSUNKNOWN="false"  PUBLISH="true" DOUBTFUL="false" USENAMECACHE="false" NAME_ID="3"/>\r
   <TAXONBASE DTYPE="Taxon" ID="5" SEC_ID="2" CREATED="2008-02-04 09:56:07.0" UUID="17233b5e-74e7-42fc-bc37-522684657ed4" UPDATED="2008-12-10 09:56:07.253" TITLECACHE="Smerinthus Latreille, 1802 sec. cate-sphingidae.org" PROTECTEDTITLECACHE="true" PUBLISH="true" TAXONSTATUSUNKNOWN="false"  DOUBTFUL="false" USENAMECACHE="false" NAME_ID="5"/>\r