Манипуляция XML с массивом в нем - PullRequest
0 голосов
/ 10 июля 2020

У меня есть входящее XML Я хотел преобразовать в другой формат. Я не получаю желаемого результата.

Входящие XML:

<aggResponse>
   <services>
      <serviceIdentifier>vStatus</serviceIdentifier>
      <Access>Allow</Access>
   </services>
   <services>
      <serviceIdentifier>vAccess</serviceIdentifier>
      <Access>Reject</Access>
      <ErrorCode>200504</ErrorCode>
   </services>
   <services>
      <serviceIdentifier>vLavel</serviceIdentifier>
      <Access>Allow</Access>
   </services>
</aggResponse>

Требуется вывод:

<NS1:Response xmlns:NS1="http://test.com">
   <NS1:checkDetail>
      <NS1:Detail>
         <NS1:AuthCheckType>vStatus</NS1:AuthCheckType>
         <NS1:Result>Allow</NS1:Result>
         <NS1:ErrorCode />
         <NS1:checkDetail />
      </NS1:Detail>
      <NS1:Detail>
         <NS1:AuthCheckType>vAccess</NS1:AuthCheckType>
         <NS1:Result>Allow</NS1:Result>
         <NS1:ErrorCode />
         <NS1:checkDetail />
      </NS1:Detail>
      <NS1:Detail>
         <NS1:AuthCheckType>vLavel</NS1:AuthCheckType>
         <NS1:Result>Reject</NS1:Result>
         <NS1:ErrorCode>200504</NS1:ErrorCode>
         <NS1:checkDetail />
      </NS1:Detail>
   </NS1:checkDetail>
   <NS1:Access>Reject</NS1:Access>
   <NS1:ErrorCode>200504</NS1:ErrorCode>
</NS1:Response>

Я использую приведенный ниже XSLT для преобразования. XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:dpconfig="http://www.datapower.com/param/config" version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="dp dpconfig">
   <xsl:output method="xml" />
   <xsl:template match="/">
      <xsl:variable name="overallAccess" select="'Allow'" />
      <xsl:variable name="errorCode" select="0" />
      <NS1:Response xmlns:NS1="http://test.com">
         <NS1:checkDetail>
            <xsl:for-each select="//*[local-name()='aggResponse']/*[local-name()='services']">
               <NS1:Detail>
                  <NS1:AuthCheckType>
                     <xsl:value-of select="*[local-name()='serviceIdentifier']" />
                  </NS1:AuthCheckType>
                  <NS1:Result>
                     <xsl:value-of select="*[local-name()='Access']" />
                  </NS1:Result>
                  <NS1:ErrorCode>
                     <xsl:value-of select="*[local-name()='ErrorCode']" />
                  </NS1:ErrorCode>
                  <xsl:variable name="overallAccesstemp">
                     <xsl:value-of select="*[local-name()='Access']" />
                  </xsl:variable>
                  <xsl:variable name="authAccess">
                     <xsl:choose>
                        <xsl:when test="$overallAccesstemp='Reject'">
                           <xsl:variable name="overallAccess" select="'Reject'" />
                           <xsl:variable name="errorCode" select="*[local-name()='ErrorCode']" />
                        </xsl:when>
                        <xsl:when test="$overallAccesstemp='Reject_needmorepoint' and $overallAccess='Allow' ">
                           <xsl:variable name="overallAccess" select="'Reject_needmorepoint'" />
                           <xsl:variable name="errorCode" select="*[local-name()='ErrorCode']" />
                        </xsl:when>
                        <xsl:otherwise>
                           <xsl:variable name="overallAccess" select="'Allow'" />
                           <xsl:variable name="errorCode" select="0" />
                        </xsl:otherwise>
                     </xsl:choose>
                  </xsl:variable>
                  <NS1:checkDetail />
               </NS1:Detail>
            </xsl:for-each>
         </NS1:checkDetail>
         <NS1:Access>
            <xsl:value-of select="$authAccess" />
         </NS1:Access>
         <NS1:ErrorCode>
            <xsl:value-of select="$errorCode" />
         </NS1:ErrorCode>
      </NS1:Response>
   </xsl:template>
</xsl:stylesheet>

Входящий XML - это динамический c, означающий, что значение тега «Доступ» может быть либо 1. Разрешить, 2. Отклонить, 3. Отклонить_morepoint. . условие 1. поэтому, если все как «Разрешить», то окончательный доступ - это «Разрешить», условие 2. если хотя бы одно - «Отклонить», то окончательный доступ - «Отклонить». Условие 3: если все - Reject_morepoint, окончательный доступ - Reject_morepoint. Для Разрешить код ошибки всегда будет 0, а во всех остальных случаях это должен быть код ошибки, который мы получаем из входящего запроса. Вот почему я пытался записать logi c внутри для l oop, что не совсем работает.

Может кто-нибудь подскажет, в чем проблема в xslt. Как получить желаемый результат

1 Ответ

0 голосов
/ 10 июля 2020

Есть ли причина, по которой вы не можете сделать просто:

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="/aggResponse">
    <NS1:Response xmlns:NS1="http://test.com">
        <NS1:checkDetail>
            <xsl:for-each select="services">
                <NS1:Detail>
                    <NS1:AuthCheckType>
                        <xsl:value-of select="serviceIdentifier"/>
                    </NS1:AuthCheckType>
                    <NS1:Result>
                        <xsl:value-of select="Access"/>
                    </NS1:Result>
                    <NS1:ErrorCode>
                        <xsl:value-of select="ErrorCode"/>
                    </NS1:ErrorCode>
                    <NS1:checkDetail/>
                </NS1:Detail>
            </xsl:for-each>
        </NS1:checkDetail>
        <xsl:variable name="access" select="services[serviceIdentifier='vAccess']" />
        <NS1:Access>
            <xsl:value-of select="$access/Access" />
        </NS1:Access>
        <NS1:ErrorCode>
            <xsl:value-of select="$access/ErrorCode" />
        </NS1:ErrorCode>
    </NS1:Response>
</xsl:template>

</xsl:stylesheet>

PS никогда не должно быть повода использовать хак вроде *[local-name()='xyz'].

Добавлено в ответ на ваше дополнительное требование:

Вот пример реализации ваших 3 правил для заполнения элемента NS1:Access. Как я уже упоминал в комментарии к вашему вопросу, эти правила не являются исчерпывающими в совокупности, поэтому вам нужно будет добавить их, чтобы охватить все возможные сценарии ios:

    <xsl:variable name="access" select="services/Access" />
    <NS1:Access>
        <xsl:choose>
            <!-- 1. all are Allow -->
            <xsl:when test="not($access != 'Allow')">Allow</xsl:when>
            <!-- 2. at least one is Reject  -->
            <xsl:when test="$access = 'Reject'">Reject</xsl:when>
            <!-- 3. all are  Reject_morepoint  -->
            <xsl:when test="not($access != 'Reject_morepoint')">Reject_morepoint</xsl:when>
        </xsl:choose>
    </NS1:Access>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...