pentaho/pentaho-kettle · error · KettleException

GetXMLData.Log.UnableApplyXPath (localized message)

Error message

GetXMLData.Log.UnableApplyXPath (localized message)

What it means

In streaming mode, processStreaming calls applyXPath() to locate matching nodes for the current document fragment. If applyXPath returns false, the step throws a KettleException carrying the localized message GetXMLData.Log.UnableApplyXPath — meaning the XPath could not be applied to the streamed document.

Solutions

  1. Correct the XPath expression in the step's 'Loop XPath' / field XPath settings
  2. Test the XPath against a sample document in a tool like XPath tester before using it in streaming mode
  3. Validate the document structure matches the streaming loop path
  4. Use non-streaming mode temporarily to get more detailed XPath errors

Example fix

// before
Loop XPath: //records/record[@id]
// after (valid, simpler XPath)
Loop XPath: //records/record
Defensive patterns

Strategy: validation

Validate before calling

try {
  org.dom4j.DocumentHelper.createXPath(loopXPath);
  org.dom4j.DocumentHelper.createXPath(fieldXPath);
} catch (Exception e) {
  failFast("Invalid XPath in GetXMLData config: " + e.getMessage());
}

Try / catch

try { runTransformation(); }
catch (KettleException ke) {
  if (ke.getMessage() != null && ke.getMessage().contains("Could not apply XPath")) {
    logError("Fix Loop XPath / field XPath in GetXMLData settings");
  }
}

Prevention

When it happens

Trigger: onEnd triggers processStreaming for a row and applyXPath() returns false — typically an invalid XPath expression, or the XPath cannot be compiled/evaluated against the dom4j document in streaming mode.

Common situations: Typo or unsupported syntax in the XPath field; XPath using features unsupported by the streaming parser; document fragment missing the nodes the XPath expects.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/75d870e3459eb658. Report an issue: GitHub.

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/getxmldata/GetXMLData.java:242

    // we're processing one row at a time through here.
    if ( data.PathValue.equals( data.prunePath ) ) {
      data.an.set( 0, (AbstractNode) row );
      data.nodesize = 1; // it's always just one row.
      data.nodenr = 0;
      if ( log.isDebug() ) {
        logDebug( BaseMessages.getString( PKG, "GetXMLData.Log.StreamingMode.ProcessingRows" ) );
      }
      Object[] r = getXMLRowPutRowWithErrorhandling();
      if ( !data.errorInRowButContinue ) { // do not put out the row but continue
        putRowOut( r ); // false when limit is reached, functionality is there but we can not stop reading the hole file
                        // (slow but works)
      }
      data.nodesize = 0;
      data.nodenr = 0;
      return;
    } else {
      if ( !applyXPath() ) {
        throw new KettleException( BaseMessages.getString( PKG, "GetXMLData.Log.UnableApplyXPath" ) );
      }
    }
    // main loop through the data until limit is reached or transformation is stopped
    // similar functionality like in BaseStep.runStepThread
    if ( log.isDebug() ) {
      logDebug( BaseMessages.getString( PKG, "GetXMLData.Log.StreamingMode.ProcessingRows" ) );
    }
    boolean cont = true;
    while ( data.nodenr < data.nodesize && cont && !isStopped() ) {
      Object[] r = getXMLRowPutRowWithErrorhandling();
      if ( data.errorInRowButContinue ) {
        continue; // do not put out the row but continue
      }
      cont = putRowOut( r ); // false when limit is reached, functionality is there but we can not stop reading the hole
                             // file (slow but works)
    }
    if ( log.isDebug() ) {
      logDebug( BaseMessages.getString( PKG, "GetXMLData.Log.StreamingMode.FreeMemory" ) );

View on GitHub (pinned to f3058517a1)