Project

Profile

Help

Bug #6406

closed

A collection cannot contain the same document more than once

Added by Norm Tovey-Walsh 6 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Low
Category:
-
Sprint/Milestone:
-
Start date:
2024-04-29
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:

Description

The (infernal) constraint that document-uri()s must be unique shouldn't apply when it's the same document. See src/test/java/s9apitest/TestCollections.java#testCollectionDupDoc.

The problem appears to arise from the fact that CollectionFn creates a new TreeInfo for each member of the collection and DocumentPool objects to two different TreeInfo objects with the same URI.

Given that QT4 is planning to remove the document-uri() restriction, it's tempting to add a configuration property that instructs Saxon to ignore this test, but it's unclear what other consequences that might have. And that's not exactly the same problem as the same node appearing in the collection more than once.

Another obvious solution is to maintian a mapping of items to TreeInfo items when the collection is being constructed:

            Map<Item,TreeInfo> infoMapping = new HashMap<>();
            for (Item item; (item = iter.next()) != null; ) {
                if (item instanceof NodeInfo && ((NodeInfo) item).getNodeKind() == Type.DOCUMENT) {
                    String docUri = ((NodeInfo) item).getSystemId();
                    DocumentKey docKey;
                    if (packageData instanceof StylesheetPackage) {
                        StylesheetPackage pack = (StylesheetPackage) packageData;
                        docKey = new DocumentKey(docUri, pack.getPackageName(), pack.getPackageVersion());
                    } else {
                        docKey = new DocumentKey(docUri);
                    }
                    final TreeInfo info;
                    if (item instanceof TreeInfo) {
                        info = (TreeInfo) item;
                    } else if (infoMapping.containsKey(item)) {
                        info = infoMapping.get(item);
                    } else {
                        info = new GenericTreeInfo(controller.getConfiguration(), (NodeInfo) item);
                        infoMapping.put(item, info);
                    }
                    //TreeInfo info = item instanceof TreeInfo ? (TreeInfo) item : new GenericTreeInfo(controller.getConfiguration(), (NodeInfo) item);
                    docPool.add(info, docKey);
                }
            }

But is that the best choice?

Please register to edit this issue

Also available in: Atom PDF