сравнить 2 XML и сделать отсортированный - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть требование для создания окончательного XML путем сравнения данных в 2 XML

Исходный XML:

    <multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
  <multimap:Message1>
    <FSE_BKLOG xmlns:ns1="http://www.w3.org/2005/Atom"
               xmlns:ns2="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
               xmlns:ns3="http://schemas.microsoft.com/ado/2007/08/dataservices"
               xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
               xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
      <FSE_BKLOGType>
        <FSE_ID>1</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>259</T_COUNT>
      </FSE_BKLOGType>
      <FSE_BKLOGType>
        <FSE_ID>2</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>128</T_COUNT>
      </FSE_BKLOGType>
      <FSE_BKLOGType>
        <FSE_ID>3</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>76</T_COUNT>
      </FSE_BKLOGType>
    </FSE_BKLOG>
  </multimap:Message1>
  <multimap:Message2>
    <FSE_BKLOG>
      <FSE_BKLOGType>
        <FSE_ID>2</FSE_ID>
        <T_COUNT>101</T_COUNT>
        <TICKET_TYPE>T</TICKET_TYPE>
      </FSE_BKLOGType>
      <FSE_BKLOGType>
        <FSE_ID>3</FSE_ID>
        <T_COUNT>101</T_COUNT>
        <TICKET_TYPE>T</TICKET_TYPE>
      </FSE_BKLOGType>
      <FSE_BKLOGType>
        <FSE_ID>4</FSE_ID>
        <T_COUNT>100</T_COUNT>
        <TICKET_TYPE>T</TICKET_TYPE>
      </FSE_BKLOGType>
    </FSE_BKLOG>
  </multimap:Message2>
</multimap:Messages>

Мое требование - зайти внутрь Message1 / FSE_BKLOG / FSE_BKLOGType / FSE_ID и сравните FSE_ID с тем, который присутствует внутри Message2 / FSE_BKLOG / FSE_BKLOGType / FSE_ID если значение совпадает, окончательное значение xml будет иметь PUT, иначе POST

Целевой XML:

<Message>
    <FSE_BKLOGType>
        <Method>POST</Method>
        <FSE_ID>1</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>259</T_COUNT>
    </FSE_BKLOGType>
    <FSE_BKLOGType>
        <Method>PUT</Method>    
        <FSE_ID>2</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>128</T_COUNT>
    </FSE_BKLOGType>
    <FSE_BKLOGType>
        <Method>PUT</Method>    
        <FSE_ID>3</FSE_ID>
        <TICKET_TYPE>T</TICKET_TYPE>
        <T_COUNT>76</T_COUNT>
    </FSE_BKLOGType>
</FSE_BKLOG>
</Message>

Вот что я попробовал: это дает мне те, которые являются общими, но пропускает ту, которая присутствует в message1.

  <xsl:template match="/">
    <ns2:Messages>
      <Message1>
        <FSE_BKLOG>
          <xsl:for-each select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType">
            <xsl:variable name="pos" select="position()"/>            
            <xsl:for-each select="/ns2:Messages/ns2:Message2/FSE_BKLOG/FSE_BKLOGType">
              <xsl:choose>
                <xsl:when test="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/FSE_ID = FSE_ID">
                  <FSE_BKLOGType>
                    <METHOD>PUT</METHOD>
                    <FSE_ID>
                      <xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/FSE_ID"/>
                    </FSE_ID>
                    <T_COUNT>
                      <xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/T_COUNT"/>
                    </T_COUNT>
                    <TICKET_TYPE>
                      <xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/TICKET_TYPE"/>
                    </TICKET_TYPE>
                  </FSE_BKLOGType>
                </xsl:when>
              </xsl:choose>
            </xsl:for-each>
          </xsl:for-each>
        </FSE_BKLOG>
      </Message1>
    </ns2:Messages>
  </xsl:template>

Спасибо Ятан

1 Ответ

0 голосов
/ 02 ноября 2018

Я бы посоветовал вам использовать ключ для поиска значения в другой ветви входного XML. Вот простой пример:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="msg2" match="multimap:Message2/FSE_BKLOG/FSE_BKLOGType" use="FSE_ID" />

<xsl:template match="/multimap:Messages">
    <Message>
        <xsl:for-each select="multimap:Message1/FSE_BKLOG/FSE_BKLOGType">
            <xsl:copy>
                <Method>
                    <xsl:choose>
                        <xsl:when test="key('msg2', FSE_ID)">PUT</xsl:when>
                        <xsl:otherwise>POST</xsl:otherwise>
                    </xsl:choose>
                </Method>
                <xsl:copy-of select="*"/>
            </xsl:copy>
        </xsl:for-each>
    </Message>
</xsl:template>

</xsl:stylesheet>

Примечание : я не удосужился удалить избыточные объявления пространства имен, которые копируются в вывод, потому что (а) это не точка вашего вопроса и (б) точный метод зависит в версии XSLT вы можете использовать (см .: Как имитировать copy-namespaces = "no" в XSLT 1.0? ).

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