Project

Profile

Help

Bug #6525

open

XdmNode::getChildren() returns always null - Should be array

Added by Fernando J. Martin 3 months ago. Updated 4 days ago.

Status:
New
Priority:
Normal
Category:
-
Start date:
2024-09-05
Due date:
% Done:

0%

Estimated time:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Found in version:
Fixed in version:
SaxonC Languages:
SaxonC Platforms:
All
SaxonC Architecture:

Description

Version/Platform:
SaxonC-EE 12.5 (compiled in Linux)

Summary:
After validating an XSD schema and getting the report, XdmNode::getChildren() returns always null even though there are errors (nodes).

Reproduce Steps:
Executing this code you'll get comparison between getChildren() which returns NULL vs. getting first node's child XdmNode and grabbing attributes and values manually.

<?php

require 'vendor/autoload.php';

use Saxon\SaxonProcessor;

putenv('SAXONC_HOME=.saxon');

$xsdSchema = 'schema.xsd';
$schemaString = '<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string" />
        <xs:element name="age" type="xs:integer" />
        <xs:element name="email" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>';
file_put_contents($xsdSchema, $schemaString);

$xmlFile = 'payload.xml';
$xmlString = '<?xml version="1.0" encoding="UTF-8"?>
<person>
  <name>Jane Doe</name>
  <age>twenty-five</age>
  <email>jane.doe@example</email>
</person>';
file_put_contents($xmlFile, $xmlString);

$processor = new SaxonProcessor(true);
$validator = $processor->newSchemaValidator();
$validator->registerSchemaFromFile($xsdSchema);
$validator->setProperty('report-node', true);

try {
    $validator->validate($xmlFile);
} catch (Exception $e) {

    $report = $validator->getValidationReport();
    echo '=============================='.PHP_EOL;
    echo '=== $report->getChildren() ==='.PHP_EOL;
    echo '=============================='.PHP_EOL;
    var_dump($report->getChildren());
    echo '=============================='.PHP_EOL;

    echo PHP_EOL . PHP_EOL;

    echo '=========================================='.PHP_EOL;
    echo '=== $report->getChildNode(0) iteration ==='.PHP_EOL;
    echo '=========================================='.PHP_EOL;
    $xmlDocument = $processor->parseXmlFromFile($xmlFile);
    $xpathProcessor = $processor->newXPathProcessor();
    $xpathProcessor->setContextItem($xmlDocument);
    $reportNode = $report->getChildNode(0);

    for ($i = 0; $i < $reportNode->getChildCount(); $i++) {
        $node = $reportNode->getChildNode($i);
        $attributes = $node->getAttributeNodes();

        if (!$attributes) {
            continue;
        }

        $message = $node->getStringValue();
        $nodeName = $node->getNodeName();
        $nodeValue = $node->getStringValue();
        preg_match('/<([^<>]+)>/', $message, $matches);
        $extracted = $matches[1];

        /** @var \Saxon\XdmNode $attributeNode */
        foreach ($node->getAttributeNodes() as $attributeNode) {
            $message = $node->getStringValue();
            match ($attributeNode->getNodeName()) {
                'line' => $line = $attributeNode->getStringValue(),
                'column' => $column = $attributeNode->getStringValue(),
                'path' => $path = $attributeNode->getStringValue(),
                default => null,
            };
        }
        $invalidNode = $xpathProcessor->evaluateSingle($path);
        $invalidNodeValue = $invalidNode?->getStringValue();

        echo "Message: $message".PHP_EOL;
        echo "Node Name: $nodeName".PHP_EOL;
        echo "Node Value: $nodeValue".PHP_EOL;
        echo 'Invalid element: '.$extracted.PHP_EOL;
        echo 'Invalid Value: '.$invalidNodeValue.PHP_EOL;
        echo 'Line: '.$line.PHP_EOL;
        echo 'Column: '.$column.PHP_EOL;
        echo 'Path: '.$path.PHP_EOL;
    }
}

Outcome of the previous code:

==============================
=== $report->getChildren() ===
==============================
NULL
==============================


==========================================
=== $report->getChildNode(0) iteration ===
==========================================
Message: The content "twenty-five" of element <age> does not match the required simple type. Cannot convert string "twenty-five" to an integer: contains a character 't'(#x74) that is not a digit
Node Name: Q{http://saxon.sf.net/ns/validation}error
Node Value: The content "twenty-five" of element <age> does not match the required simple type. Cannot convert string "twenty-five" to an integer: contains a character 't'(#x74) that is not a digit
Invalid element: age
Invalid Value: twenty-five
Line: 4
Column: 25
Path: /Q{}person[1]/Q{}age[1]
Actions #1

Updated by Martin Honnen 3 months ago

The problems appears to to exist with any XdmNode in the PHP API, even a simple

$xml = <<<XML
<root att1="value 1" att2="value 2">
  <foo>bar</foo>
</root>
<!-- comment 1 -->
XML;

$saxonProc = new Saxon\SaxonProcessor();

$xdmNode = $saxonProc->parseXmlFromString($xml);

echo $xdmNode->getChildCount();

$root =  $xdmNode->getChildNode(0);
$attributes = $root->getAttributeNodes();

var_dump($attributes);

$children = $xdmNode->getChildren();

var_dump($children);

outputsan array for getAttributeNodes but NULL for the getChildren.

2array(2) {
  [0]=>
  object(Saxon\XdmNode)#4 (0) {
  }
  [1]=>
  object(Saxon\XdmNode)#5 (0) {
  }
}
NULL
Actions #2

Updated by Martin Honnen 3 months ago

The example https://saxonica.plan.io/projects/saxonmirrorhe/repository/he/revisions/he_mirror_saxon_12_5/entry/src/main/c/samples/php/xpathExamples.php#L159 also fails to output the children.

Not sure why that stuff doesn't work from PHP, it appears to be working with C++ and Python.

Actions #3

Updated by Michael Kay 3 months ago

  • Project changed from Saxon to SaxonC
  • Category deleted (Schema-Aware processing)
  • SaxonC Platforms All added
Actions #4

Updated by O'Neil Delpratt 4 days ago

  • Assignee set to Matt Patterson

Please register to edit this issue

Also available in: Atom PDF