2013-04-02 100 views
0

我想添加一個基於日期比較新的元素。如果父DATE在最近7天內,我想添加一個新元素。我編寫了代碼來進行日期比較,但我很難弄清楚在哪裏放置它。目前,它在模板中重新格式化父DATE,但這會導致我的新元素在日期元素內。有沒有辦法在當前元素之外創建一個新元素?謝謝。XSLT添加新節點之外當前節點的

我輸入

<?xml version="1.0" encoding="UTF-8"?> 
<NOTICES> 
    <PRESOL> 
     <DATE>03012013</DATE> 
     <AGENCY><![CDATA[Department of the Interior]]></AGENCY> 
     <OFFICE><![CDATA[Fish and Wildlife Service]]></OFFICE> 
     <LOCATION><![CDATA[CGS-WO]]></LOCATION> 
     <ZIP>97232</ZIP> 
     <CHANGES> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>US</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </PRESOL> 
    <COMBINE> 
     <DATE>03012013</DATE> 
     <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
     <OFFICE><![CDATA[Air Force Materiel Command]]></OFFICE> 
     <LOCATION><![CDATA[Tinker OC-ALC - (Central Contracting)]]></LOCATION> 
     <ZIP>73145-3015</ZIP> 
    </COMBINE> 
    <COMBINE> 
     <DATE>03052013</DATE> 
     <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
     <OFFICE><![CDATA[Military Sealift Command]]></OFFICE> 
     <LOCATION><![CDATA[MSC Norfolk]]></LOCATION> 
    </COMBINE> 
    <COMBINE> 
     <DATE>03292013</DATE> 
     <AGENCY><![CDATA[Department of Veterans Affairs]]></AGENCY> 
     <OFFICE><![CDATA[Grand Junction VAMC)]]></OFFICE> 
     <LOCATION><![CDATA[Veterans Affairs Medical Center]]></LOCATION> 
    </COMBINE> 
    <PRESOL> 
     <DATE>03302013</DATE> 
     <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
     <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
     <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
     <CHANGES> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>US</COUNTRY> 
      </MOD> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>UK</COUNTRY> 
      </MOD> 
      <MOD> 
       <DATE>01142013</DATE> 
       <COUNTRY>JAPAN</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </PRESOL> 
    <FAIROPP> 
     <DATE>04012013</DATE> 
     <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
     <OFFICE><![CDATA[Bureau of Medicine and Surgery]]></OFFICE> 
     <LOCATION><![CDATA[NH Camp Pendleton]]></LOCATION> 
     <ZIP>92055</ZIP> 
     <CHANGES> 
      <MOD> 
        <DATE>02122011</DATE> 
        <COUNTRY>JAPAN</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </FAIROPP> 
</NOTICES> 

所需的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<NOTICES> 
    <PRESOL> 
     <DATE>03012013</DATE> 
     <AGENCY><![CDATA[Department of the Interior]]></AGENCY> 
     <OFFICE><![CDATA[Fish and Wildlife Service]]></OFFICE> 
     <LOCATION><![CDATA[CGS-WO]]></LOCATION> 
     <ZIP>97232</ZIP> 
     <CHANGES> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>US</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </PRESOL> 
    <COMBINE> 
     <DATE>03012013</DATE> 
     <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
     <OFFICE><![CDATA[Air Force Materiel Command]]></OFFICE> 
     <LOCATION><![CDATA[Tinker OC-ALC - (Central Contracting)]]></LOCATION> 
     <ZIP>73145-3015</ZIP> 
    </COMBINE> 
    <COMBINE> 
     <DATE>03052013</DATE> 
     <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
     <OFFICE><![CDATA[Military Sealift Command]]></OFFICE> 
     <LOCATION><![CDATA[MSC Norfolk]]></LOCATION> 
    </COMBINE> 
    <COMBINE> 
     <DATE>03292013</DATE> 
     **<mostrecent>YES</mostrecent>** 
     <AGENCY><![CDATA[Department of Veterans Affairs]]></AGENCY> 
     <OFFICE><![CDATA[Grand Junction VAMC)]]></OFFICE> 
     <LOCATION><![CDATA[Veterans Affairs Medical Center]]></LOCATION> 
    </COMBINE> 
    <PRESOL> 
     <DATE>03302013</DATE> 
     **<mostrecent>YES</mostrecent>** 
     <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
     <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
     <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
     <CHANGES> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>US</COUNTRY> 
      </MOD> 
      <MOD> 
       <DATE>01112013</DATE> 
       <COUNTRY>UK</COUNTRY> 
      </MOD> 
      <MOD> 
       <DATE>01142013</DATE> 
       <COUNTRY>JAPAN</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </PRESOL> 
    <FAIROPP> 
     <DATE>04012013</DATE> 
     **<mostrecent>YES</mostrecent>** 
     <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
     <OFFICE><![CDATA[Bureau of Medicine and Surgery]]></OFFICE> 
     <LOCATION><![CDATA[NH Camp Pendleton]]></LOCATION> 
     <ZIP>92055</ZIP> 
     <CHANGES> 
      <MOD> 
        <DATE>02122011</DATE> 
        <COUNTRY>JAPAN</COUNTRY> 
      </MOD> 
     </CHANGES> 
    </FAIROPP> 
</NOTICES> 

我的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     exclude-result-prefixes="xs"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" cdata-section-elements="AGENCY DESC CLASSCOD CONTACT DATE NAICS LINK OFFADD OFFICE SUBJECT ZIP AGENCY ZIP"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:variable name="backdate1" select="current-date() -7*xs:dayTimeDuration('P1D')"/> 
    <xsl:variable name="backdate" select="xs:date(substring($backdate1, 1, 10))"/> 
    <!-- copy all nodes --> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="DATE/text()"> 
<!-- format DATE mm/dd/yyyy --> 
     <xsl:value-of select="concat(substring(., 1, 2), '/', substring(., 3, 2), '/', substring(., 5, 4))"/> 
    **<!-- add new node mostrecent if date is within the last 7 days --> 
     <xsl:variable name="subtract_date" select="days-from-duration(xs:date(concat(substring(., 5, 4), '-', substring(., 1, 2), '-', substring(., 3, 2))) - xs:date(substring($backdate1, 1, 10)))"/> 
     <xsl:if test="$subtract_date &gt;= 0"> 
     <xsl:text disable-output-escaping="yes">&lt;</xsl:text> 
     <xsl:text disable-output-escaping="yes">mostrecent</xsl:text> 
     <xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
     <xsl:text disable-output-escaping="yes">&lt;/</xsl:text> 
     <xsl:text disable-output-escaping="yes">mostrecent</xsl:text> 
     <xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
     </xsl:if>** 
    </xsl:template> 

    <!-- keep only the parent date node and delete all children date nodes --> 
    <xsl:template match="DATE[../ancestor::*/DATE]"/> 

    <!-- add new node type to each child node --> 
    <xsl:template match="NOTICES/child::node()"> 
    <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="name(.)"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
    <xsl:apply-templates select="@*|node()"/> 
     <type> 
      <xsl:value-of select ="name(.)"/> 
     </type> 
    <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="name(.)"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

回答

0

你可以做到這一點,如果你的日期元素,而不是它的文本節點上一致:

<xsl:template match="DATE"> 
     <xsl:variable name="dStr" select="string(.)" /> 
     <xsl:variable name="bdStr" select="string($backdate1)" /> 
     <!-- format DATE mm/dd/yyyy --> 
     <xsl:copy> 
      <xsl:value-of select="concat(substring($dStr, 1, 2), '/', 
             substring($dStr, 3, 2), '/', 
             substring($dStr, 5, 4))"/> 
     </xsl:copy> 
     <!-- add new node mostrecent if date is within the last 7 days --> 
     <xsl:variable name="subtract_date" 
         select="days-from-duration(xs:date(
              concat(substring($dStr, 5, 4), '-', 
               substring($dStr, 1, 2), '-', 
               substring($dStr, 3, 2))) - 
           xs:date(substring($bdStr, 1, 10)))"/> 
     <xsl:if test="$subtract_date &gt;= 0"> 
      <mostrecent>YES</mostrecent> 
     </xsl:if> 
    </xsl:template> 
+0

感謝JL,偉大的工作。問題:使用導致我的原始代碼無法工作的文本節點的是什麼? –

+0

它並沒有因爲你的方法工作,身份模板是做'DATE'元素複製到輸出,然後應用_inside_該元素模板'DATE'的兒童(包括文字)的工作。因此,在'text()'模板中可以使用的任何內容都將被輸出_inside_ DATE'元素。一旦你在那裏,沒有辦法讓它回到外面。 – JLRishe

+0

我試圖將上述xslt從1.0轉換爲2.0。當我這樣做時,我收到一個錯誤:substring()的第一個參數的必需項目類型是xs:string;提供的值具有項目類型xs:date。我不明白的是,爲什麼這個轉換工作在1.0而不是2.0以及如何解決它。我在想,2.0需要更多的變量聲明控制。此外,錯誤似乎來自我的if語句,因爲當我註釋掉它時,代碼編譯得很好。 –

相關問題