Project

General

Profile

Revision d2f1dbf2

IDd2f1dbf2c82afa64d69d596895b5cfca90c11ce8
Parent bc3200a9
Child 8b00105b

Added by Andreas Müller about 3 years ago

ref #7745 fix bug in queries with subtree, some first test and cleanup

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImpl.java
1449 1449
                boolean includeUnpublished, Classification classification, TaxonNode subtree,
1450 1450
                Set<NamedArea> areasExpanded, MatchMode matchMode, String searchField){
1451 1451

  
1452

  
1452 1453
        boolean doAreaRestriction = areasExpanded.size() > 0;
1454
        boolean hasTaxonNodeFilter = classification != null || subtree != null;
1455

  
1453 1456
        String doAreaRestrictionSubSelect =
1454 1457
                     " SELECT %s.id "
1455 1458
                   + " FROM Distribution e "
1456 1459
                   + "    JOIN e.inDescription d "
1457 1460
                   + "    JOIN d.taxon t " +
1458
                (classification != null ? " JOIN t.taxonNodes AS tn " : " ");
1461
                (hasTaxonNodeFilter ? " JOIN t.taxonNodes AS tn " : " ");
1459 1462

  
1460 1463
        String doAreaRestrictionConceptRelationSubSelect =
1461 1464
                   "SELECT %s.id "
......
1465 1468

  
1466 1469
        String doTaxonSubSelect =
1467 1470
                     " SELECT %s.id "
1468
                   + " FROM Taxon t " + (classification != null ? " "
1471
                   + " FROM Taxon t " + (hasTaxonNodeFilter ? " "
1469 1472
                           + " JOIN t.taxonNodes AS tn " : " ");
1470 1473

  
1471 1474
        String doTaxonMisappliedNameSubSelect =
......
1481 1484
        String doConceptRelationJoin =
1482 1485
                   " LEFT JOIN t.relationsFromThisTaxon AS rft " +
1483 1486
                   " LEFT JOIN rft.relatedTo AS rt " +
1484
                      (classification != null ? " LEFT JOIN rt.taxonNodes AS tn2 " : " ") +
1487
                      (hasTaxonNodeFilter ? " LEFT JOIN rt.taxonNodes AS tn2 " : " ") +
1485 1488
                   " LEFT JOIN rt.name AS n2" +
1486 1489
                   " LEFT JOIN rft.type as rtype";
1487 1490

  
......
1509 1512
        String conceptSelect = null;
1510 1513
        String commonNameSubselect = null;
1511 1514

  
1512
        if(classification != null || subtree != null){
1515
        if(hasTaxonNodeFilter){
1513 1516
            if (!doConceptRelations){
1514 1517
                if(doAreaRestriction){
1515 1518
                    taxonSubselect = String.format(doAreaRestrictionSubSelect, "t") + doTaxonNameJoin +
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.java
57 57
import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
58 58
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
59 59
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
60
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
60 61
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
61 62
import eu.etaxonomy.cdm.persistence.query.GroupByCount;
62 63
import eu.etaxonomy.cdm.persistence.query.GroupByDate;
......
78 79
    private ITaxonDao taxonDao;
79 80

  
80 81
    @SpringBeanByType
82
    private ITaxonNodeDao taxonNodeDao;
83

  
84
    @SpringBeanByType
81 85
    private IClassificationDao classificationDao;
82 86

  
83 87
    @SpringBeanByType
......
86 90
    @SpringBeanByType
87 91
    private IDefinedTermDao definedTermDao;
88 92

  
89
    private UUID uuid;
90
    private UUID sphingidae;
91
    private UUID acherontia;
92
    private UUID rethera;
93
    private UUID retheraSecCdmtest;
94
    private UUID atroposAgassiz; // a Synonym
95
    private UUID atroposOken;  // a Synonym
96
    private UUID atroposLeach; // a Synonym
97
    private UUID acherontiaLachesis;
98
    private UUID aus;
93
    private UUID uuid = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
94
    private UUID sphingidae = UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9");
95
    private UUID acherontia = UUID.fromString("c5cc8674-4242-49a4-aada-72d63194f5fa");
96
    private UUID rethera = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
97
    private UUID retheraSecCdmtest = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
98
    private UUID atroposAgassiz = UUID.fromString("d75b2e3d-7394-4ada-b6a5-93175b8751c1"); // a Synonym
99
    private UUID atroposOken = UUID.fromString("6bfedf25-6dbc-4d5c-9d56-84f9052f3b2a");  // a Synonym
100
    private UUID atroposLeach = UUID.fromString("3da4ab34-6c50-4586-801e-732615899b07"); // a Synonym
101
    private UUID acherontiaLachesis = UUID.fromString("b04cc9cb-2b4a-4cc4-a94a-3c93a2158b06");
102
    private UUID aus = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
103

  
104
    private UUID UUID_ACHERONTIA_NODE = UUID.fromString("56b10cf0-9522-407e-9f90-0c2dba263c94");
105
    private UUID UUID_CLASSIFICATION2 = UUID.fromString("a71467a6-74dc-4148-9530-484628a5ab0e");
99 106

  
100 107
    private AuditEvent previousAuditEvent;
101 108
    private AuditEvent mostRecentAuditEvent;
......
128 135
    @Before
129 136
    public void setUp() {
130 137

  
131
        uuid = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
132
        sphingidae = UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9");
133
        acherontia = UUID.fromString("c5cc8674-4242-49a4-aada-72d63194f5fa");
134
        acherontiaLachesis = UUID.fromString("b04cc9cb-2b4a-4cc4-a94a-3c93a2158b06");
135
        atroposAgassiz = UUID.fromString("d75b2e3d-7394-4ada-b6a5-93175b8751c1");
136
        atroposOken = UUID.fromString("6bfedf25-6dbc-4d5c-9d56-84f9052f3b2a");
137
        atroposLeach =  UUID.fromString("3da4ab34-6c50-4586-801e-732615899b07");
138
        rethera = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
139
        retheraSecCdmtest = UUID.fromString("a9f42927-e507-4fda-9629-62073a908aae");
140
        aus = UUID.fromString("496b1325-be50-4b0a-9aa2-3ecd610215f2");
141 138

  
142 139
        previousAuditEvent = new AuditEvent();
143 140
        previousAuditEvent.setRevisionNumber(1025);
......
472 469
        Synonym synAtroposAgassiz = (Synonym)taxonDao.findByUuid(atroposAgassiz);
473 470
        Taxon taxonRethera = (Taxon)taxonDao.findByUuid(rethera);
474 471
        taxonRethera.addSynonym(synAtroposAgassiz, SynonymType.SYNONYM_OF());
475
        logger.warn("addSynonym(..)");
472
        //logger.warn("addSynonym(..)");
476 473
        this.taxonDao.clear();
477 474
        Synonym synAtroposLeach = (Synonym)taxonDao.findByUuid(atroposLeach);
478 475
        Taxon taxonRetheraSecCdmtest = (Taxon)taxonDao.findByUuid(retheraSecCdmtest);
479 476
        taxonRetheraSecCdmtest.addSynonym(synAtroposLeach, SynonymType.SYNONYM_OF());
480 477
        this.taxonDao.clear();
478

  
481 479
        // 1. searching for a taxon (Rethera)
482 480
        //long numberOfTaxa = taxonDao.countTaxaByName(Taxon.class, "Rethera", null, MatchMode.BEGINNING, namedAreas);
483 481

  
484 482
        @SuppressWarnings("rawtypes")
485
        List<TaxonBase> results = taxonDao.findByNameTitleCache(true, false, includeUnpublished, "Rethera Rothschild & Jordan, 1903", null, subtree, MatchMode.EXACT, namedAreas,
483
        List<TaxonBase> results = taxonDao.findByNameTitleCache(doTaxa, noSynonyms, includeUnpublished, "Rethera Rothschild & Jordan, 1903", null, subtree, MatchMode.EXACT, namedAreas,
486 484
                null, null, null, null);
487 485
        assertNotNull("getTaxaByName should return a List", results);
488 486
        assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
489 487

  
490 488
        // 2. searching for a taxon (Rethera) contained in a specific classification
491
        results = taxonDao.findByNameTitleCache(true, false, includeUnpublished, "Rethera Rothschild & Jordan, 1903", classification, subtree, MatchMode.EXACT, namedAreas,
489
        results = taxonDao.findByNameTitleCache(doTaxa, noSynonyms, includeUnpublished, "Rethera Rothschild & Jordan, 1903", classification, subtree, MatchMode.EXACT, namedAreas,
492 490
                null, null, null, null);
493 491
        assertNotNull("getTaxaByName should return a List", results);
494 492
        assertTrue("expected to find one taxon but found "+results.size(), results.size() == 1);
495 493

  
496

  
497 494
        // 3. searching for Synonyms
498
        results = taxonDao.findByNameTitleCache(false, true, includeUnpublished, "*Atropo", null, subtree, MatchMode.ANYWHERE, null,
495
        results = taxonDao.findByNameTitleCache(noTaxa, doSynonyms, includeUnpublished, "*Atropo", null, subtree, MatchMode.ANYWHERE, null,
499 496
                null, null, null, null);
500 497
        assertNotNull("getTaxaByName should return a List", results);
501 498
        assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
502 499

  
503 500
        // 4. searching for Synonyms
504
        results = taxonDao.findByNameTitleCache(false, true, includeUnpublished, "Atropo", null, subtree, MatchMode.BEGINNING, null,
501
        results = taxonDao.findByNameTitleCache(noTaxa, doSynonyms, includeUnpublished, "Atropo", null, subtree, MatchMode.BEGINNING, null,
505 502
                null, null, null, null);
506 503
        assertNotNull("getTaxaByName should return a List", results);
507 504
        assertTrue("expected to find two taxa but found "+results.size(), results.size() == 2);
508 505

  
509

  
510 506
        // 5. searching for a Synonyms and Taxa
511 507
        //   attache a synonym first
512 508
        Synonym syn = (Synonym)taxonDao.findByUuid(this.atroposLeach);
......
514 510
        tax.addSynonym(syn, SynonymType.HETEROTYPIC_SYNONYM_OF());
515 511

  
516 512
        taxonDao.save(tax);
517
        results = taxonDao.findByNameTitleCache(true, true, includeUnpublished, "A", null, subtree, MatchMode.BEGINNING, namedAreas,
513
        results = taxonDao.findByNameTitleCache(doTaxa, doSynonyms, includeUnpublished, "A", null, subtree, MatchMode.BEGINNING, namedAreas,
518 514
                null, null, null, null);
519 515
        assertNotNull("getTaxaByName should return a List", results);
520 516
        assertTrue("expected to find 8 taxa but found "+results.size(), results.size() == 8);
......
597 593
    @DataSet
598 594
    public void testCountTaxaByName() {
599 595
        TaxonNode subtree = null;
600
        long numberOfTaxa = taxonDao.countTaxaByName(true, false, false, false,false, "A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
596
        Classification classification= null;
597
        long numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames,false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
601 598
        assertEquals(5, numberOfTaxa);
602
        numberOfTaxa = taxonDao.countTaxaByName(true, false, false, false, false,"Smerinthus kindermannii", null, subtree, MatchMode.EXACT, null, includeUnpublished);
599
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
600
        assertEquals("Sphingidae, Smerinthus, Smerinthus kindermannii and Sphingonaepiopsis expected", 4, numberOfTaxa);
601
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
603 602
        assertEquals(1, numberOfTaxa);
604
        numberOfTaxa = taxonDao.countTaxaByName(false, true, false, false, false,"A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
603
        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
605 604
        assertEquals(2, numberOfTaxa);
606
        numberOfTaxa = taxonDao.countTaxaByName(true, true, false, false, false,"A", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
605
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
607 606
        assertEquals(7, numberOfTaxa);
608
        numberOfTaxa = taxonDao.countTaxaByName(true, true, false, false,false, "Aasfwerfwf fffe", null, subtree, MatchMode.BEGINNING, null, includeUnpublished);
607
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
608
        assertEquals(0, numberOfTaxa);
609

  
610
        subtree = taxonNodeDao.findByUuid(UUID_ACHERONTIA_NODE);
611
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
612
        assertEquals("Acherontia and 2 A. species expected", 3, numberOfTaxa);
613
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
614
        assertEquals("", 0, numberOfTaxa);
615
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
616
        assertEquals("Smerinthus is not in subtree", 0, numberOfTaxa);
617
        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
618
        assertEquals("Atropos Agassiz and Atropos Oken expected as Synonyms", 2, numberOfTaxa);
619
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
620
        assertEquals("The above accepted and synonyms expected", 5, numberOfTaxa);
621
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
622
        assertEquals(0, numberOfTaxa);
623

  
624
        classification = classificationDao.findByUuid(UUID_CLASSIFICATION2);
625
        subtree = null;
626
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
627
        assertEquals("Acherontia and 2 A. species expected", 3, numberOfTaxa);
628
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "S", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
629
        assertEquals("Sphingidae expected", 1, numberOfTaxa);
630
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, noSynonyms, noMisapplied, noCommonNames, false, "Smerinthus kindermannii", classification, subtree, MatchMode.EXACT, null, includeUnpublished);
631
        assertEquals("Smerinthus is not in subtree", 0, numberOfTaxa);
632
        numberOfTaxa = taxonDao.countTaxaByName(noTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
633
        assertEquals("Atropos Agassiz and Atropos Oken expected as Synonyms", 2, numberOfTaxa);
634
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "A", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
635
        assertEquals("The above accepted and synonyms expected", 5, numberOfTaxa);
636
        numberOfTaxa = taxonDao.countTaxaByName(doTaxa, doSynonyms, noMisapplied, noCommonNames, false, "Aasfwerfwf fffe", classification, subtree, MatchMode.BEGINNING, null, includeUnpublished);
609 637
        assertEquals(0, numberOfTaxa);
610
//	FIXME implement test for search in specific classification
611
//		Reference reference = referenceDao.findByUuid(UUID.fromString("596b1325-be50-4b0a-9aa2-3ecd610215f2"));
612
//		numberOfTaxa = taxonDao.countTaxaByName("A*", MatchMode.BEGINNING, SelectMode.ALL, null, null);
613
//		assertEquals(numberOfTaxa, 2);
614 638
    }
615 639

  
616 640
    @Test
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.xml
20 20
  <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"/>
21 21
  <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"/>
22 22
  <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"/>
23
  <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"/>
24
  <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"/>
25
  <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]"/>
26
  <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"/>
27
  <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"/>
28
  <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]"/>
29
  <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"/>
30
  <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"/>
31
  <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"/>
32
  <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"/>
33
  
34
  
23 35
  <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" />
24 36
  <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"/>
25 37
  <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"/>

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)