XSLT для преобразования заданного запроса с заданными параметрами - PullRequest
0 голосов
/ 17 апреля 2020

Вот данные XML -

    <INPUT>
    <pSql>select * from cntwrk where moddte>= :from_date and ins_dt &lt; :to_date</parameterizedSql>
    <arguments>
    <dataType>DATETIME</dataType>
    <values>2019-07-24T00:00:01</values>
    <key>from_date</key>
    </arguments>
    <arguments>
    <dataType>DATETIME</dataType>
    <values>2019-09-23T00:00:01</values>
    <key>to_date</key>
    </arguments>
    </INPUT>

Мне нужно создать xslt, чтобы в конечном запросе было выбрано * из cntwrk, где moddte> = (to_date ('2019-07-24 00 : 00: 01 ',' гггг-мм-дд HH24: mi: ss ')) и
ins_dt <(to_date (' 2019-09-23 00:00:01 ',' гггг-мм-дд HH24: mi: ss ')) output. </p>

То есть замените: from_date аргументами / значениями после некоторой конкатенации.

Пожалуйста, найдите XSLT, который я пробовал, но не смог получить желаемый результат с используя переменные.


    <?xml version="1.0"?>
        <xsl:transform exclude-result-prefixes="xsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
          <xsl:output method="text" indent="yes" />
          <xsl:variable name="q_var" select="INPUT/parameterizedSql" />
          <xsl:param name="find_var" select="concat(':',INPUT/arguments/key)" />
          <xsl:param name="re_var" select="INPUT/arguments/values" />
          <xsl:template match="INPUT">
            <xsl:apply-templates select="arguments[dataType[text() = 'DATETIME']]" />
          </xsl:template>
          <xsl:template match="INPUT">
            <xsl:for-each select="//arguments">
              <xsl:call-template name="replace-string">
                <xsl:with-param name="text" select="$q_var" />
                <xsl:with-param name="replace" select="$find_var" />
                <xsl:with-param name="with" select="$re_var" />
              </xsl:call-template>
            </xsl:for-each>
          </xsl:template>
          <xsl:template name="replace-string">
            <xsl:param name="text" />
            <xsl:param name="replace" />
            <xsl:param name="with" />
            <xsl:choose>
              <xsl:when test="contains($text,$replace)">
                <xsl:value-of select="substring-before($text,$replace)" />
                <xsl:value-of select="$with" />
                <xsl:call-template name="replace-string">
                  <xsl:with-param name="text" select="substring-after($text,$replace)" />
                  <xsl:with-param name="replace" select="$replace" />
                  <xsl:with-param name="with" select="$with" />
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="$text" />
              </xsl:otherwise>
            </xsl:choose>
          </xsl:template>
        </xsl:transform>

1 Ответ

0 голосов
/ 17 апреля 2020

Первое, что здесь нужно узнать, это то, что xsl:for-each - это не все oop. Каждый узел в выбранном наборе узлов обрабатывается индивидуально. Вы не можете передать результат одного экземпляра другому.

Существует два возможных способа последовательной обработки заданной строки: один - это метод, называемый рекурсия брата , а другой - сквозной именованный рекурсивный шаблон . В следующем примере будет продемонстрирован 2-й метод.

Для простоты я буду предполагать, что каждый аргумент появляется в данной строке ровно один раз. Если это предположение неверно, то вам потребуется вызвать другой рекурсивный шаблон, чтобы выполнить фактическую замену текущего обработанного аргумента в данной строке при вызове следующей итерации.

XML (исправлено )

<INPUT>
    <parameterizedSql>select * from cntwrk where moddte>= :from_date and ins_dt &lt; :to_date</parameterizedSql>
    <arguments>
        <dataType>DATETIME</dataType>
        <values>2019-07-24T00:00:01</values>
        <key>from_date</key>
    </arguments>
    <arguments>
        <dataType>DATETIME</dataType>
        <values>2019-09-23T00:00:01</values>
        <key>to_date</key>
    </arguments>
</INPUT>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/INPUT">
    <OUTPUT>
        <xsl:call-template name="insert-arguments">
            <xsl:with-param name="string" select="parameterizedSql"/>
            <xsl:with-param name="arguments" select="arguments"/>
        </xsl:call-template>
    </OUTPUT>
</xsl:template>

<xsl:template name="insert-arguments">
    <xsl:param name="string"/>
    <xsl:param name="arguments"/>
    <xsl:choose>
        <xsl:when test="$arguments">
            <!-- recursive call -->
            <xsl:call-template name="insert-arguments">
                <xsl:with-param name="string">
                    <!-- insert current argument -->
                    <xsl:variable name="argument" select="$arguments[1]" />
                    <xsl:variable name="search-string" select="concat(':', $argument/key)" />
                    <xsl:value-of select="substring-before($string, $search-string)"/>
                    <xsl:value-of select="$argument/values"/>
                    <xsl:value-of select="substring-after($string, $search-string)"/>
                </xsl:with-param>
                <xsl:with-param name="arguments" select="$arguments[position() > 1]"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$string"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Результат

<?xml version="1.0" encoding="UTF-8"?>
<OUTPUT>select * from cntwrk where moddte&gt;= 2019-07-24T00:00:01 and ins_dt &lt; 2019-09-23T00:00:01</OUTPUT>

I не вижу в вашем вопросе логики c, в которые вставляемое значение необходимо обернуть в todate(), поэтому я пропустил эту часть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...