XSLT transform not providing correct output

后端 未结 1 621
离开以前
离开以前 2021-01-29 16:04

I\'m having a slight problem with my XSLT transform.

I have the following XSLT;




        
相关标签:
1条回答
  • 2021-01-29 16:45

    There are a number of issues with your XSLT. Focusing on the problem in hand, one issue is in one of your "order" templates uses an xsl:copy-of

     <xsl:template match="order">
        <order job_id="{@job_id}" site_code="{@site_code}" replace="{Replace}">
            <xsl:apply-templates select="node()"/>
            <xsl:copy-of select="../master_version"/>
         </order>
     </xsl:template>
    

    Before going further though, you have two templates matching "order". This is strictly speaking specified as an error in XSLT. You may not actually be seeing an error because some processors ignore the duplicate templates, and only use the last one. You should delete the first one.

    Anyway, by using xsl:copy-of it is simply going to copy all master_version elements here, regardless of any other template matches here. You need to use xsl:apply-templates

    <xsl:template match="order">
       <order job_id="{@job_id}" site_code="{@site_code}" replace="{Replace}">
          <xsl:apply-templates select="node()"/>
          <xsl:apply-templates select="../master_version"/>
       </order>
    </xsl:template>
    

    But this on its own will not work because of these two template matches (although it is an error to have to templates both matching just master_version as mentioned)

    <xsl:template match="job_id | site_code | replace | master_version"/>
    
    <xsl:template match="Replace | master_version"/>
    

    Remove the master_version from these template matches, and leave just this existing one

    <xsl:template match="master_version[not(ORDER = //order/ORDERPK)]"/>
    

    (Note that when an element is matched with a condition, it will actually have a higher priority than one that just matched master_version, so this is not an error in this instance).

    You would also be there at this point, but you would find now that master_version would still be output in their current place too. To get around this, you can have a template matching dataroot and add code to explicitly ignore the master_version elements at that point

    <xsl:template match="dataroot">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()[not(self::master_version)]"/>
      </xsl:copy>
    </xsl:template>
    

    Try this XSLT. It may not give the precise output you specified, but it should solve the problem on your master_version elements which you asked about:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
       <xsl:template match="master_version[not(ORDER = //order/ORDERPK)]"/>
    
       <xsl:template match="press_section[not(ORDER = //order/ORDERPK)]"/>
       <xsl:template match="version[not(ORDER = //order/ORDERPK)]"/>
       <xsl:template match="task_info_press_section[not(ORDER = //order/ORDERPK)]"/>
       <xsl:template match="task_info_post_press[not(ORDER = //order/ORDERPK)]"/>
       <xsl:template match="post_press_version[not(ORDER = //order/ORDERPK)]"/>
       <!-- removes specified nodes from all elements -->
    
       <xsl:template match="ORDER"/>
       <xsl:template match="ORDERPK"/>
       <xsl:template match="PRESS_x0020_SECTION"/>
       <xsl:template match="POST_x0020_PRESS"/>
    
       <!-- Creates attributes against the ORDER element -->
       <xsl:strip-space elements="*"/>
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:template match="dataroot">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()[not(self::master_version)]"/>
          </xsl:copy>
       </xsl:template>
    
       <xsl:template match="job_id | site_code | replace | Replace"/>
    
       <!-- identity transform -->
       <xsl:template match="@*|node()">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
       </xsl:template>
    
       <xsl:template match="order">
          <order job_id="{@job_id}" site_code="{@site_code}" replace="{Replace}">
             <xsl:apply-templates select="node()"/>
             <xsl:apply-templates select="../master_version"/>
          </order>
       </xsl:template>
    
       <xsl:template match="task_info_press_section">
          <xsl:element name="task_info1">
             <xsl:apply-templates/>
          </xsl:element>
       </xsl:template>
    
       <xsl:template match="task_info_post_press">
          <xsl:element name="task_info2">
             <xsl:apply-templates/>
          </xsl:element>
       </xsl:template>
    </xsl:stylesheet>
    

    Also note the multiple identity templates have been removed, as mentioned by Daniel Haley in comments.

    0 讨论(0)
提交回复
热议问题