Модификация элемента из узла с помощью xslt 1.0 - PullRequest
0 голосов
/ 28 февраля 2019

Я использую XSLT 1.0 для преобразования XML (входной) в другой XML (выходной).Я столкнулся с проблемой, когда мне не удалось преобразовать один из элементов определенного узла в XSLT.

Вот мой входной XML:

    <?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
     <payload>
       <order>
          <Id>12345</Id>
          <dateDelivery>2018-03-29T14:00:00 EST</dateDelivery>
          <play>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
          </play>
          <play>
            <title>Esque</title>
            <artist>Bylan</artist>
            <country>CA</country>
            <company>bia</company>
            <price>16.90</price>
            <year>2018</year>
          </play>         
       </order>
     </payload>
  </cd>
 </catalog>

XSLT:

    <?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
            <SOAP-ENV:Body>
                <SongUpdate_Request>
                    <xsl:apply-templates select="//cd"/>
                </SongUpdate_Request>
            </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>
    </xsl:template>
    <xsl:template match="//cd">
        <xsl:call-template name="getHeader"/>
        <xsl:call-template name="getPayload"/>
    </xsl:template>
    <xsl:template name="getHeader">
        <header>
            <header>
                <Id_T>
                    <xsl:value-of select="//payload/order/Id"/>
                </Id_T>
            </header>
        </header>
    </xsl:template>
    <xsl:template name="getPayload">
        <songEvent>
            <xsl:call-template name="getOrder"/>
        </songEvent>
    </xsl:template>
    <xsl:template name="replace">
        <xsl:param name="dd"/>
        <xsl:param name="searchString"> EST</xsl:param>
        <xsl:param name="replaceString">.000Z</xsl:param>
        <xsl:choose>
            <xsl:when test="contains($dd,$searchString)">
                <xsl:value-of select="substring-before($dd,$searchString)"/>
                <xsl:value-of select="$replaceString"/>
                <!--  recursive call -->
                <xsl:call-template name="replace">
                    <xsl:with-param name="dd" select="substring-after($dd,$searchString)"/>
                    <xsl:with-param name="searchString" select="$searchString"/>
                    <xsl:with-param name="replaceString" select="$replaceString"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$dd"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="getOrder">      
            <xsl:call-template name="replace">
                <xsl:with-param name="dd" select="//*:payload/*:order/*:dateDelivery"/>
            </xsl:call-template>
        <xsl:variable name="OrderPresent">
            <xsl:value-of select=".//*:order"/>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$OrderPresent!=''">
                <xsl:copy-of select=".//*:order"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Выходной XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Body>
      <SongUpdate_Request>
         <header>
            <header>
               <Id_T>12345</Id_T>
            </header>
         </header>
         <songEvent>2018-03-29T14:00:00.000Z
                <order>
                  <Id>12345</Id>
                  <dateDelivery>2018-03-29T14:00:00 EST</dateDelivery>
                     <play>
                           <title>Empire Burlesque</title>
                           <artist>Bob Dylan</artist>
                           <country>USA</country>
                           <company>Columbia</company>
                           <price>10.90</price>
                           <year>1985</year>
                     </play>
                     <play>
                           <title>Esque</title>
                           <artist>Bylan</artist>
                           <country>CA</country>
                           <company>bia</company>
                           <price>16.90</price>
                           <year>2018</year>
                     </play>          
               </order>
         </songEvent>
      </SongUpdate_Request>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Поэтому, если вы наблюдаете, я пытаюсь изменить формат даты с EST на "Z".Но я не уверен, как применять при преобразовании в XSLT.Это означает, что я хочу видеть вывод xml вроде:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Body>
      <SongUpdate_Request>
         <header>
            <header>
               <Id_T>12345</Id_T>
            </header>
         </header>
         <songEvent>
                <order>
                  <Id>12345</Id>
                  *<dateDelivery>2018-03-29T14:00:00.000Z</dateDelivery>*
                     <play>
                           <title>Empire Burlesque</title>
                           <artist>Bob Dylan</artist>
                           <country>USA</country>
                           <company>Columbia</company>
                           <price>10.90</price>
                           <year>1985</year>
                     </play>
                     <play>
                           <title>Esque</title>
                           <artist>Bylan</artist>
                           <country>CA</country>
                           <company>bia</company>
                           <price>16.90</price>
                           <year>2018</year>
                     </play>          
               </order>
         </songEvent>
      </SongUpdate_Request>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Любые предложения или помощь очень приветствуются.Спасибо !!

1 Ответ

0 голосов
/ 01 марта 2019

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

<xsl:template match="dateDelivery">
    <xsl:copy>
        <xsl:value-of select="substring(., 1, 19)"/>
        <xsl:text>.000Z</xsl:text>
    </xsl:copy>
</xsl:template>

Вот полная таблица стилей, которая производит XML, показанный в вашем вопросе:

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:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/catalog">
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
        <SOAP-ENV:Body>
            <SongUpdate_Request>
                <xsl:apply-templates select="cd/payload"/>
            </SongUpdate_Request>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
</xsl:template>

<xsl:template match="payload">
    <header>
        <header>
            <Id_T>
                <xsl:value-of select="order/Id"/>
            </Id_T>
        </header>
    </header>
    <songEvent>
        <xsl:apply-templates/>
    </songEvent>    
</xsl:template>

<xsl:template match="dateDelivery">
    <xsl:copy>
        <xsl:value-of select="substring(., 1, 19)"/>
        <xsl:text>.000Z</xsl:text>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Примечание:
Как уже упоминалось в комментариях к вашему вопросу, изменяет фактическое значение элемента dateDelivery, делая егоНа 5 часов раньше исходного времени.

...