Я пытаюсь преобразовать множество XSL-преобразований в XSLT 3.0, чтобы я мог воспользоваться преимуществами потоковой передачи, поскольку большая часть XML, с которой я имею дело, довольно велика. У меня проблема с этим относительно простым преобразованием. Мне дано понять, что copy-of()
должен разрешать несколько операндов-потребителей, но Саксон по-прежнему жалуется на это.
Когда я пытаюсь применить этот XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday/bsvc"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:mode streamable="yes"/>
<xsl:strip-space elements="*" />
<!-- Identity template -->
<xsl:template match="/">
<ROOT>
<xsl:apply-templates select="/ROOT/ROW/copy-of(.)" />
</ROOT>
</xsl:template>
<xsl:template match="ROW">
<xsl:if test="contains(WD_BATCH_ID, 'timeoff_corr')" >
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
... на XML, который выглядит следующим образом:
<ROOT>
<ROW>
<INT_ID>229274</INT_ID>
<WD_BATCH_ID>kns_timeoff20200105_5365_78659138_TEST</WD_BATCH_ID>
<WD_PAY_INPUT_ID>229174</WD_PAY_INPUT_ID>
<DATE_WORKED>2019-12-31</DATE_WORKED>
<EMPLOYEE_ID>103839</EMPLOYEE_ID>
<WEEK_END_DATE>2020-01-05</WEEK_END_DATE>
<EFFECTIVE_DATE>2020-01-05</EFFECTIVE_DATE>
<HOURS>2</HOURS>
<PAY_COMPONENT>INVALID_TIMEOFF1</PAY_COMPONENT>
<TK_COMMENTS>kns_timeoff20200105_5365_78659138</TK_COMMENTS>
<SS_REQUEST_ID>78658686</SS_REQUEST_ID>
<REQUEST_ID>78659138</REQUEST_ID>
<PROCESS_DATE>2020-02-10</PROCESS_DATE>
<PROCESS_STATUS>C</PROCESS_STATUS>
</ROW>
<ROW>
<INT_ID>1008269</INT_ID>
<WD_BATCH_ID>kns_wd20200105_26285_78659138_TEST</WD_BATCH_ID>
<WD_PAY_INPUT_ID>WK2.1008269</WD_PAY_INPUT_ID>
<DATE_WORKED>2020-01-05</DATE_WORKED>
<EMPLOYEE_ID>101113</EMPLOYEE_ID>
<WEEK_END_DATE>2020-01-05</WEEK_END_DATE>
<EFFECTIVE_DATE>2020-01-05</EFFECTIVE_DATE>
<HOURS>40</HOURS>
<PAY_COMPONENT>INVALID_CODE1</PAY_COMPONENT>
<TK_COMMENTS>kns_wd20200105_26285_78659138</TK_COMMENTS>
<SS_REQUEST_ID>78658686</SS_REQUEST_ID>
<REQUEST_ID>78659138</REQUEST_ID>
<PROCESS_DATE>2020-02-10</PROCESS_DATE>
<PROCESS_STATUS>C</PROCESS_STATUS>
</ROW>
<ROW>
<INT_ID>234387</INT_ID>
<WD_BATCH_ID>kns_timeoff_corr_test_7_78668139</WD_BATCH_ID>
<WD_PAY_INPUT_ID>234386</WD_PAY_INPUT_ID>
<DATE_WORKED>2019-12-12</DATE_WORKED>
<EMPLOYEE_ID>150389</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-15</WEEK_END_DATE>
<EFFECTIVE_DATE>2020-01-05</EFFECTIVE_DATE>
<HOURS>-9</HOURS>
<PAY_COMPONENT>Jury Duty</PAY_COMPONENT>
<TK_COMMENTS>kns_wd20200105_7_78668139</TK_COMMENTS>
<SS_REQUEST_ID>78668068</SS_REQUEST_ID>
<REQUEST_ID>78668139</REQUEST_ID>
<PROCESS_DATE>2020-02-19</PROCESS_DATE>
<PROCESS_STATUS>C</PROCESS_STATUS>
</ROW>
</ROOT>
... он должен выдавать идентичные XML, но пропустить любые ROW
узлы, в которых дочерний элемент WD_BATCH_ID
не содержит timeoff_corr
. Это работает, как и ожидалось, без объявленной потоковой передачи, но с потоковой передачей, объявленной «да», Саксон жалуется net.sf.saxon.trans.XPathException: Template rule is declared streamable but it does not satisfy the streamability rules. * There is more than one consuming operand: {contains(...)} on line 17, and {xsl:copy-of} on line 18
Конечно, есть contains()
17 и xsl:copy-of
18, но в соответствии с Saxon использование select="/ROOT/ROW/copy-of(.)"
должно разрешить «не потоковые» операции с копией этого узла.
Чего мне не хватает, что мешает этому XSL быть потоковым?