Project

Profile

Help

Bug #6381

closed

set_unprefixed_element_matching_policy(1) doesn't seem to work

Added by Martin Honnen 8 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Category:
Internals
Sprint/Milestone:
-
Start date:
2024-03-31
Due date:
% Done:

100%

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

Description

I wrote the following Python code making use of set_unprefixed_element_matching_policy(1) on an PyXPathProcessor:

from saxonche import PySaxonProcessor

with PySaxonProcessor() as saxon_proc:
    print(saxon_proc.version)

    xpath_processor = saxon_proc.new_xpath_processor()

    xpath_processor.set_unprefixed_element_matching_policy(1)

    xpath_processor.set_context(file_name='sample1.xml')

    print(xpath_processor.evaluate('/root/foo'))

    xpath_processor.set_context(file_name='sample2.xml')

    print(xpath_processor.evaluate('/root/foo'))

Output:

SaxonC-HE 12.4.2 from Saxonica
None
None

Sample XML files are attached.

A similar Java program (also attached) outputs:

12.4                                                                
<foo xmlns="http://example.com/ns-2023">bar</foo>

<foo xmlns="http://example.com/ns-2023">baz</foo>
<foo xmlns="http://example.com/ns-2024">bar</foo>

<foo xmlns="http://example.com/ns-2024">baz</foo>

I would have expected the Python program to select and output the same nodes as the Java program, instead, despite the policy set, no nodes seem to be selected.


Files

main.py (457 Bytes) main.py Martin Honnen, 2024-03-31 14:45
JavaDefaultNamespaceTest1.java (823 Bytes) JavaDefaultNamespaceTest1.java Martin Honnen, 2024-03-31 14:45
sample1.xml (90 Bytes) sample1.xml Martin Honnen, 2024-03-31 14:45
sample2.xml (90 Bytes) sample2.xml Martin Honnen, 2024-03-31 14:45
Actions #1

Updated by Martin Honnen 8 months ago

I have tried to find Python and/or C++ samples but there is only https://saxonica.plan.io/projects/saxonmirrorhe/repository/he/revisions/he_mirror_saxon_12_4_2/entry/src/main/c/samples/cppTests/testXPath.cpp#L40 which simply uses a namespace wildcard //*:person[1], it doesn't look like the use of the set_unprefixed_element_matching_policy or its C++ counterpart has been tested.

Actions #2

Updated by O'Neil Delpratt 8 months ago

Thanks for reporting the issue. I have reproduced the same output as you:

SaxonC-HE 12.4.2 from Saxonica
None
None

Looking at the path through the code there is nothing obvious that I can see that could be causing the issue. We will investigate this more when we are back in the office.

Actions #3

Updated by Martin Honnen 8 months ago

I tried to find from C++ what could be failing and wrote e.g.

void testUnprefixedElementMatchingPolicy1(SaxonProcessor* processor,
    XPathProcessor* xpath,
    sResultCount* sresult) {

    cout << endl << "Test testUnprefixedElementMatchingPolicy1:" << endl;
    XdmNode* node = processor->parseXmlFromString(
        "<root xmlns=\"http://example.com/ns\"><person>person 1</person><person>person 2</person></root>");
    xpath->setContextItem((XdmItem*)node);
    xpath->setUnprefixedElementMatchingPolicy(UnprefixedElementMatchingPolicy::ANY_NAMESPACE);
    try {

        XdmItem* result = xpath->evaluateSingle("//person");
        if (result == nullptr) {
            cout << "No node found by XPath //person without prefix." << endl;
            sresult->failure++;
            sresult->failureList.push_back("testUnprefixedElementMatchingPolicy1");
        }
        else {
            const char* resultStr = result->getStringValue();
            cout << "String Value of result=" << resultStr << endl;
            sresult->success++;
            delete result;
            operator delete((char*)resultStr);
        }
    }
    catch (SaxonApiException& e) {
        cout << "Error Message = " << e.what() << endl;
        sresult->failure++;
        sresult->failureList.push_back("testUnprefixedElementMatchingPolicy1");
    }

    xpath->clearParameters();
    xpath->clearProperties();

    delete node;
}

enabled the debug flag but that outputs a lot of info without giving (me?) a clue why SaxonC fails to apply the policy:

Test testUnprefixedElementMatchingPolicy1:
Java DEBUG toJavaString: no encoding found
New documentBuilder obj: 357531500
DEBUG: builder.getBaseURI= null
DEBUG: parseXML doc.getBaseURI=
xmlParseString, Processor: 922056896
documentBuilder obj: 357531500
XdmNode: 1478289948
Object Handles created: 2
Properties size: 2
Parameter size: 1
Object Handles created: 3
Java DEBUG toJavaString: no encoding found
ProcessorDataAccumulator - data-pair - addProcessor paramName= node
ProcessorDataAccumulator - data-pair - addProcessorValue= net.sf.saxon.s9api.XdmNode
Java DEBUG toJavaString: no encoding found
Java DEBUG toJavaString: no encoding found
ProcessorDataAccumulator - pair - addProcessor paramName= resources
ProcessorDataAccumulator - pair - addProcessorValue=
Java DEBUG toJavaString: no encoding found
Java DEBUG toJavaString: no encoding found
ProcessorDataAccumulator - pair - addProcessor paramName= uemp:
ProcessorDataAccumulator - pair - addProcessorValue= 1
Java DEBUG toJavaString: no encoding found
Java DEBUG toJavaString: no encoding found
Java DEBUG toJavaString: no encoding found
xpathString: //person
value [0] = net.sf.saxon.s9api.XdmNode
value [1] = java.lang.String
value [2] = java.lang.String
DEBUG: SaxonCAPI: param-name: node, type of Value= net.sf.saxon.s9api.XdmNode
DEBUG: SaxonCAPI: param-name: uemp:, type of Value= java.lang.String
DEBUG setUnprefixedElementMatchingPolicy value=1
DEBUG setUnprefixedElementMatchingPolicy size=3
DEBUG: Type of value=net.sf.saxon.s9api.XdmNode
applyXPathProperties: parameters map is empty
Object Handles created: 4
destroy method Class to be deleted= net.sf.saxon.option.cpp.ProcessorDataAccumulator
Destroyed Object Handle.  Current count: 3
No node found by XPath //person without prefix.
~XdmNode destructor called:0 ob ref=00000254385BE4C0
~XdmItem destructor called:0 ob ref=00000254385BE4C0value =9
destroy method Class to be deleted= net.sf.saxon.s9api.XdmNode
Destroyed Object Handle.  Current count: 2
Actions #4

Updated by O'Neil Delpratt 8 months ago

  • Status changed from New to In Progress

Internally we call setAllowUndeclaredVariables(true). Currently this is affecting the setUnprefixedElementMatchingPolicy.

Background: https://saxonica.plan.io/issues/4356

Investigating this further.

Actions #5

Updated by Martin Honnen 8 months ago

So this is looking like a bug or quirk on the Java side of Saxon that setting allow undeclared variables on XPathCompiler affects the unprefixed element matching policy?

Actions #6

Updated by O'Neil Delpratt 8 months ago

Yes I think this is a bug. Currently there is no workaround because we do not expose setAllowUndeclaredVariables()

Actions #7

Updated by O'Neil Delpratt 8 months ago

  • Project changed from SaxonC to Saxon
  • Category changed from Python API to Internals
  • Applies to branch 12 added

This is indeed a bug against the Java product. I am switching this over to the main bug tracker.

Actions #8

Updated by Martin Honnen 8 months ago

I am able to find the same failure of element matching policy not working once undeclared variables are allowed in SaxonCS 12.4:

    using Saxon.Api;

    var processor = new Processor();

    var docBuilder = processor.NewDocumentBuilder();

    var doc = docBuilder.Build(new Uri(Path.Combine(Environment.CurrentDirectory, "sample1.xml")));

    var xpathCompiler = processor.NewXPathCompiler();

    xpathCompiler.UnprefixedElementMatchingPolicy = UnprefixedElementMatchingPolicy.AnyNamespace;

    Console.WriteLine($"Results any namespace, default undeclared variables:\n{xpathCompiler.Evaluate("/root/foo", doc)}");

    xpathCompiler.AllowUndeclaredVariables = true;

    Console.WriteLine($"Results any namespace, allow undeclared variables:\n{xpathCompiler.Evaluate("/root/foo", doc)}");

    xpathCompiler.AllowUndeclaredVariables = false;

    Console.WriteLine($"Results any namespace, disallow undeclared variables:\n{xpathCompiler.Evaluate("/root/foo", doc)}");

outputs e.g.

Results any namespace, default undeclared variables:
<foo xmlns="http://example.com/ns-2023">bar</foo>
<foo xmlns="http://example.com/ns-2023">baz</foo>
Results any namespace, allow undeclared variables:

Results any namespace, disallow undeclared variables:
<foo xmlns="http://example.com/ns-2023">bar</foo>
<foo xmlns="http://example.com/ns-2023">baz</foo>

with sample1.xml being e.g.

<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="http://example.com/ns-2023">
  <foo>bar</foo>
  <foo>baz</foo>
</root>
Actions #9

Updated by O'Neil Delpratt 8 months ago

Yes I am not surprised as its the same base code across the three products. We have a fix for this.

Actions #10

Updated by Martin Honnen 8 months ago

Oh, you already have a fix. Didn't understand that from the issue status but then I will just wait for the next maintenance release.

Actions #11

Updated by Michael Kay 8 months ago

Current status is that we know exactly how to fix it but we haven't actually fixed it yet.

Actions #12

Updated by Matt Patterson 8 months ago

  • Assignee changed from O'Neil Delpratt to Matt Patterson
  • Fix Committed on Branch 12 added

This is now fixed on the 12 branch, for both Java and SaxonC. It will be released in the next maintenance release.

Actions #13

Updated by Michael Kay 7 months ago

  • Status changed from In Progress to Resolved
  • Applies to branch trunk added
  • Fix Committed on Branch trunk added
  • Platforms .NET, Java added
Actions #14

Updated by O'Neil Delpratt 5 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 12.5 added

Bug fix applied in the Saxon 12.5 Maintenance release.

Please register to edit this issue

Also available in: Atom PDF