【问题标题】:XSLT - Delete XML nodes comparing datesXSLT - 删除比较日期的 XML 节点
【发布时间】:2021-03-09 20:05:20
【问题描述】:

对于以下 XML,当字段 StartDate 不等于单元 5000 的任何 StartDate 项时,我需要删除仅单元 6000 的所有 XML 节点

我试图匹配一个模板,但似乎是一个很好的匹配

<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
   <Records>
      <Record>
         <Items>
            <EndDate>2021-03-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST1</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2020-12-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST2</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2020-05-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2021-02-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST3</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-02-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2020-12-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>2000</company>
                  <Newplant>TEST4</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2020-01-01T00:00:00.000</StartDate>
            <Unit>6000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2021-03-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>2010</company>
                  <Newplant>TEST5</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-01T00:00:00.000</StartDate>
            <Unit>6000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2021-06-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>2020</company>
                  <Newplant>TEST5</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-093T00:00:00.000</StartDate>
            <Unit>6000</Unit>
            <Status>A</Status>
         </Items>
      </Record>
   </Records>
</AllRecords>
 

xslt 代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
    </xsl:stylesheet>
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />
    <xsl:template match="@*|node()">
     <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
      </xsl:template>
    <xsl:variable name="date" select="xs:date(//Items[Status = 'A' and ( Unit=6000)) ]/StartDate
    <xsl:template match="$date eq xs:date(//Items[Status = 'A' and Unit='5000']/StartDate)"/>
    </xsl:stylesheet>

删除单元 6000 XML 节点后预期输出 XSLT 代码,因为这 2 个节点的日期与 5000 的 xml 节点中的任何一个都不匹配

<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
   <Records>
      <Record>
         <Items>
            <EndDate>2021-03-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST1</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2020-12-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST2</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2020-05-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2021-02-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>1000</company>
                  <Newplant>TEST3</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-01T00:00:00.000</StartDate>
            <Unit>5000</Unit>
            <Status>A</Status>
         </Items>
         <Items>
            <EndDate>2021-03-31T00:00:00.000</EndDate>
            <PlantDetails>
               <PlantDetailsUS>
                  <company>2010</company>
                  <Newplant>TEST5</Newplant>
               </PlantDetailsUS>
            </PlantDetails>
            <StartDate>2021-01-01T00:00:00.000</StartDate>
            <Unit>6000</Unit>
            <Status>A</Status>
         </Items>
      </Record>
   </Records>
</AllRecords>

【问题讨论】:

    标签: xslt xslt-1.0 xslt-2.0


    【解决方案1】:

    当字段 StartDate 不等于单元 5000 的任何 StartDate 项时,删除仅单元 6000 的所有 XML 节点

    使用 key 应该很容易做到这一点:

    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="*"/>
    
    <xsl:key name="k1" match="Items[Unit=5000]" use="StartDate" />
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- remove items that do not have a matching item -->
    <xsl:template match="Items[Unit=6000][not(key('k1', StartDate))]"/>
    
    </xsl:stylesheet>
    

    【讨论】:

    【解决方案2】:

    除了@micheal.hor257kanswer,这类问题用简单的XPath/XSLT就可以轻松解决patterns

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
      <xsl:output method="xml" indent="yes"/>  
      <xsl:strip-space elements="*"/>  
      <xsl:template match="@*|node()"> 
        <xsl:copy> 
          <xsl:apply-templates select="@*|node()"/> 
        </xsl:copy> 
      </xsl:template>  
      <xsl:template 
           match="Items[Unit=6000][not(StartDate = ../Items[Unit=5000]/StartDate)]"/> 
    </xsl:stylesheet>
    

    查看here

    【讨论】:

    • 谢谢。我也在尝试检查 EndDate 是否不小于当前时间并且它没有按预期工作
    猜你喜欢
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多