Копировать, удалять и изменять значение элемента при выполнении условия - PullRequest
0 голосов
/ 28 мая 2018

У меня есть xml:

<?xml version="1.0" ?>
 <pi:A xmlns:pi="urn:com.workday/picof">
      <pi:PG>
           <pi:EE>
                <pi:S>
                     <pi:EE_ID>ABC123</pi:EE_ID>
                     <pi:PGN>OS</pi:PGN>
                </pi:S>
                <pi:ED>
                     <pi:C>402B</pi:C>
                     <pi:SD>2017-04-01</pi:SD>
                </pi:ED>
                <pi:ED>
                     <pi:C>402C</pi:C>
                     <pi:SD>2017-05-01</pi:SD>
                </pi:ED>
                <pi:AI>
                     <pi:IRS>2018-05-01</pi:IRS>
                </pi:AI>
           </pi:EE>
      </pi:PG>
      <pi:PG>
           <pi:EE>
                <pi:S>
                     <pi:EE_ID>XYZ789</pi:EE_ID>
                     <pi:PGN>OR</pi:PGN>
                </pi:S>
                <pi:ED>
                     <pi:C>401A</pi:C>
                     <pi:SD>1996-04-29</pi:SD>
                </pi:ED>
                <pi:ED>
                     <pi:C>402F</pi:C>
                     <pi:SD>2017-03-01</pi:SD>
                </pi:ED>
                <pi:AI>
                     <pi:IRS>2018-06-01</pi:IRS>
                </pi:AI>
           </pi:EE>
      </pi:PG>
 </pi:A>

И xsl:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:pi="urn:com.workday/picof"
 version="2.0">

<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <pi:A>
        <pi:PG>
        <xsl:for-each select="//pi:EE">
        <pi:EE>
            <xsl:copy-of select="pi:S"/>
            <xsl:apply-templates select="pi:ED"/>
        </pi:EE>
        </xsl:for-each>
        </pi:PG>
    </pi:A>     
</xsl:template>

<xsl:variable name="EDS" select="pi:A/pi:PG/pi:EE/pi:AI/pi:IRS"/>

<xsl:template match="pi:ED">
    <pi:ED>
        <pi:C>
            <xsl:value-of select="pi:C"/>
        </pi:C>
        <pi:SD>
            <xsl:choose>
                <xsl:when test="pi:C='402F' and pi:C='402B'">
                    <xsl:value-of select="$EDS"/>
                </xsl:when>
                <xsl:when test="pi:C!='402B' and pi:C!='402F'">
                    <xsl:value-of select="pi:SD"/>
                </xsl:when>               
                <xsl:otherwise/>
            </xsl:choose>  
        </pi:SD>
    </pi:ED>         
</xsl:template>


</xsl:stylesheet>

Но мой xsl ничего не делает.Я попытался изменить код и смог получить гораздо лучший результат, но тогда переменная просто выбрасывала пустое значение.

Мне просто нравится, что мой окончательный вывод удалит pi: AI, а затем скопирует оставшиеся,Но если pi: C равно 402B или 402F, тогда pi: SD должно использовать значение из pi: AI.Так оно и должно выглядеть.

<?xml version="1.0" ?>
<pi:A xmlns:pi="urn:com.workday/picof">
  <pi:PG>
       <pi:EE>
            <pi:S>
                 <pi:EE_ID>ABC123</pi:EE_ID>
                 <pi:PGN>OS</pi:PGN>
            </pi:S>
            <pi:ED>
                 <pi:C>402B</pi:C>
                 <pi:SD>2018-05-01</pi:SD>
            </pi:ED>
            <pi:ED>
                 <pi:C>402C</pi:C>
                 <pi:SD>2017-05-01</pi:SD>
            </pi:ED>
       </pi:EE>
  </pi:PG>
  <pi:PG>
       <pi:EE>
            <pi:S>
                 <pi:EE_ID>XYZ789</pi:EE_ID>
                 <pi:PGN>OR</pi:PGN>
            </pi:S>
            <pi:ED>
                 <pi:C>401A</pi:C>
                 <pi:SD>1996-04-29</pi:SD>
            </pi:ED>
            <pi:ED>
                 <pi:C>402F</pi:C>
                 <pi:SD>2018-06-01</pi:SD>
            </pi:ED>
       </pi:EE>
  </pi:PG>

Может кто-нибудь помочь, пожалуйста?Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Valdi_Bo дал ответ на ваш вопрос, но если вы заинтересованы в расширении своих знаний по XSLT, вам может быть интересно узнать, можно ли значительно упростить свой XSLT с помощью Identity Template

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

Это будет обрабатывать копирование любых элементов, которые вы не хотите изменять, так что вам нужно беспокоиться только о написании шаблонов для необходимых вам изменений

Итак, чтобы удалить элементы pi:AIиметь шаблон для игнорирования их

<xsl:template match="pi:AI" />

Для обновления pi:SD, где pi:C - это "402F" или "402B", иметь шаблон, соответствующий этим элементам, и просто обновлять конкретные

<xsl:template match="pi:ED[pi:C='402F' or pi:C='402B']/pi:SD">
    <xsl:copy>
        <xsl:value-of select="../../pi:AI/pi:IRS" />
    </xsl:copy>
</xsl:template>

Попробуйте это XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pi="urn:com.workday/picof"
                version="2.0">

  <xsl:output method="xml" html-version="5"/>

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

  <xsl:template match="pi:AI" />

  <xsl:template match="pi:ED[pi:C='402F' or pi:C='402B']/pi:SD">
      <xsl:copy>
          <xsl:value-of select="../../pi:AI/pi:IRS" />
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Обратите внимание: поскольку вы используете XSLT 2.0, вы можете написать второе совпадение шаблона следующим образом ...

<xsl:template match="pi:ED[pi:C = ('402F', '402B')]/pi:SD">
0 голосов
/ 28 мая 2018

Примечание строка <xsl:when test="pi:C='402F' and pi:C='402B'"> в вашем скрипте.

pi:C не может быть одновременно равным 402F и 402B.

Изменить and на or.

Еще одно исправление: измените <xsl:value-of select="$EDS"/> на <xsl:value-of select="../pi:AI/pi:IRS"/>

Причина в том, что вы скопировали все значения pi:IRS без необходимости.Вам следует скопировать только «локальное» значение.

...