[xsl] How to select elements containing ARPT but not elements containing APPC_ARPT or ARPT_RMK?

Subject: [xsl] How to select elements containing ARPT but not elements containing APPC_ARPT or ARPT_RMK?
From: "Roger L Costello costello@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 22 Oct 2022 18:21:13 -0000
Hi Folks,

Here is my input:

<test>
  <row>
    <column_header>A</column_header>
    <affected_tables>ARPT_RMK</affected_tables>
  </row>
  <row>
    <column_header>B</column_header>
    <affected_tables>APPC_ARPT</affected_tables>
  </row>
  <row>
    <column_header>C</column_header>
    <affected_tables>HLPT; ARPT</affected_tables>
  </row>
  <row>
    <column_header>D</column_header>
    <affected_tables>HLPT; ARPT; VFR_RTE</affected_tables>
  </row>
  <row>
    <column_header>E</column_header>
    <affected_tables>ARPT; VFR_RTE</affected_tables>
  </row>
  <row>
    <column_header>F</column_header>
    <affected_tables>ARPT</affected_tables>
  </row>
  <row>
    <column_header></column_header>
    <affected_tables>ARPT</affected_tables>
  </row>
</test>

I want to output the column_headers of all rows whose affected_tables contain
ARPT.

The desired output is:

    <column_header>C</column_header>
    <column_header>D</column_header>
    <column_header>E</column_header>
    <column_header>F</column_header>

I thought that this XSLT would work:

<xsl:for-each select="//row[column_header][matches(affected_tables, '[
;]?ARPT[ ;]?')]">
    <column_header><xsl:value-of select="column_header"/></column_header>
</xsl:for-each>

I interpret that for-loop as: "Iterate through all row elements and output the
column_header of each row element that has a non-null child column_header
element and has a child affected_tables element that contains the string ARPT
which is optionally preceded by a space or a semi-colon and optionally
followed by a space or a semi-colon."

Apparently that is not what the for-loop says because it produces this
incorrect output:

    <column_header>A</column_header>
    <column_header>B</column_header>
    <column_header>C</column_header>
    <column_header>D</column_header>
    <column_header>E</column_header>
    <column_header>F</column_header>
    <column_header/>

Two questions:

1. What does my for-loop actually say?
2. What is a correct solution?

/Roger

Current Thread