Узел сборки XSL на основе ключа
ВХОД:
<?xml version="1.0" encoding="UTF-8"?>
<comtec>
<record id="1">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-JUNIOR</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867139</column>
</record>
<record id="2">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="3">
<column name="id_task">44422</column>
<column name="capabilityCode">AVS</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="4">
<column name="id_task">60038</column>
<column name="PropertyDescr">ReqMissing</column>
<column name="capabilityCode">FR-AUTOPLAN</column>
<column name="ResCapString">FR-RDV1, FR-GGE1, FR-PARC2, FR-RDV VIP</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
<record id="5">
<column name="id_task">60038</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
</comtec>
Желаемый результат:
<comtec>
<task_order>
<id>1867139</id>
<capabilities>
<capability>
<capability_code>FR-JUNIOR</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<required>true</required>
</capability>
<capability>
<capability_code>AVS</capability_code>
<required>true</required>
</capability>
</capabilities>
<task>
<id>1867139</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
<task_order>
<id>1867454</id>
<capabilities>
<capability>
<capability_code>FR-AUTOPLAN</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<available>true</available>
</capability>
</capabilities>
<task>
<id>1867454</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
</comtec>
Привет. Требуемый вывод основан на следующей логике: id_task имеет несколько записей: а) если значения только в столбце "ColMiss", тогда создайте пустой тег возможности (второй тег записи в выводе); б) если он имеет значения в обоих "ColMiss". Затем column и ColHave создают тег возможности, используя только значения из столбца CapabilityCode в записях, у которых ColHave не равен NULL.
Я надеюсь, что это имеет смысл, я все еще новичок с ключами /var частями XSL, и я работаю над некоторыми примерами, чтобы понять.
Спасибо
ОБНОВИТЬ:
Текущий XSL - без ключей / переменных
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=
generate-id(key('record',
record/column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',
column[@name='id_task'])/
column[@name='ColMiss']"/>
<xsl:choose>
<xsl:when test="$values ='miss'">
<xsl:for-each select="$values ='miss'">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<available>true</available>
</capability>
</xsl:for-each>
</xsl:when>
<xsl:when test="$values =''">
<xsl:for-each select="$values =''">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<required>true</required>
</capability>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Как вы можете видеть, проблема в том, что он не группирует теги "возможностей" под одним родителем, но создает тег для каждой записи, что является нормальным из-за реализованной логики. Но я подумал, что есть и другой способ, кроме использования ключа / переменной.
На основании этого XSL есть ли способ перейти к желаемому выводу?
Еще раз спасибо
1 ответ
Я не мог полностью проработать вашу логику, но первая проблема, с которой вы столкнулись, это то, как вы определили свой ключ
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
Это будет искать record
стихия, ища ребенка record
элементы их, что не соответствует тому, что у вас есть в вашем XML. Так и должно быть...
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
Точно так же, когда вы используете этот ключ в мюнхенской группировке...
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
Существует также проблема с вашим xsl:for-each
...
<xsl:for-each select="$values ='miss'">
Это недопустимо, потому что результат $values ='miss'
либо "истинно", либо "ложно", и xsl:for-each
требует выбора узлов, а не логического значения.
В любом случае, попробуйте этот XSLT. Это не даст вам результат, который вам нужен, потому что я вполне мог бы проработать вашу точную логику, но это может дать вам лучшую отправную точку...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',column[@name='id_task'])/column[@name='ColMiss']"/>
<xsl:for-each select="key('record',column[@name='id_task'])">
<capability>
<capability_code>
<xsl:value-of select="column[@name='capabilityCode']"/>
</capability_code>
<xsl:choose>
<xsl:when test="$values[. ='miss']">
<required>true</required>
</xsl:when>
<xsl:otherwise>
<available>true</available>
</xsl:otherwise>
</xsl:choose>
</capability>
</xsl:for-each>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, выражение как $values[. ='']
если какое-либо из значений пустое, не обязательно все из них. Если вы хотите проверить все пробелы, вам придется сделать not($values[. != ''])
(то есть не существует того, который не является пустым).