满足条件时复制,删除和更改元素的值

时间:2018-05-28 14:39:46

标签: xml xslt xslt-2.0

我有一个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 :(得分:2)

在脚本中注意行<xsl:when test="pi:C='402F' and pi:C='402B'">

pi:C不能同时等于402F402B

and更改为or

另一项更正:将<xsl:value-of select="$EDS"/>更改为<xsl:value-of select="../pi:AI/pi:IRS"/>

原因是您不必要地复制了所有pi:IRS值。 你应该只复制&#34; local&#34;值。

答案 1 :(得分:0)

Valdi_Bo已经给出了你的问题的答案,但是如果你热衷于扩展你的XSLT知识,你可能有兴趣知道你可以通过Identity Template

大大简化你的XSLT。
<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是&#34; 402F&#34;或&#34; 402B&#34;,具有与这些元素匹配的模板,只需更新特定的元素

<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">