2013-02-17 53 views
0

我有一個大的XML文件,我試圖編寫XSLT,它循環遍歷整個節點集(PRESOL,COMBINE和FAIROPS)並刪除名爲DATE的所有子節點。然後,我想將父節點的DATE重新格式化爲mm/dd/yyyy。這裏是我的代碼,我使用的是1.0版本:XSLT循環XML文件,刪除子項,重新格式化日期

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="DATE"> 
    <xsl:text> 
    </xsl:text> 
    <xsl:text disable-output-escaping="yes">&lt;</xsl:text> 
    <xsl:value-of select="name()"/> 
    <xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
    <xsl:value-of select="concat(substring(., 1, 2), '/', substring(., 3, 2), '/', substring(., 5, 4))"/> 
    <xsl:text disable-output-escaping="yes">&lt;/</xsl:text> 
    <xsl:value-of select="name()"/> 
    <xsl:text disable-output-escaping="yes">&gt;</xsl:text> 
    <xsl:text> 
    </xsl:text> 
</xsl:template> 
<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="DATE[preceding::DATE]"/> 

我有一個很難理解如何通過一個完整的節點集循環。我希望不要硬編碼父節點名稱。目前,我的代碼只處理第一個父節點。另外,如果一個父節點沒有孩子,我的代碼正在刪除它的DATE節點,我不明白爲什麼。任何幫助將不勝感激。

我的輸入

<NOTICES> 
    <PRESOL> 
    <DATE>01242013</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>01242013</DATE> 
    <AGENCY><![CDATA[Department of the Interior]]></AGENCY> 
    <OFFICE><![CDATA[Fish and Wildlife Service]]></OFFICE> 
    <LOCATION><![CDATA[CGS-WO]]></LOCATION> 
    <ZIP>97232</ZIP> 
    </MOD> 
    </CHANGES> 
    </PRESOL> 
    <COMBINE> 
    <DATE>02102013</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>02092013</DATE> 
    <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
    <OFFICE><![CDATA[Military Sealift Command]]></OFFICE> 
    <LOCATION><![CDATA[MSC Norfolk]]></LOCATION> 
    </COMBINE> 
    <COMBINE> 
    <DATE>02092013</DATE> 
    <AGENCY><![CDATA[Department of Veterans Affairs]]></AGENCY> 
    <OFFICE><![CDATA[Grand Junction VAMC)]]></OFFICE> 
    <LOCATION><![CDATA[Veterans Affairs Medical Center]]></LOCATION> 
    </COMBINE> 
    <PRESOL> 
    <DATE>12272012</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> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <DATE>01112013</DATE> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <DATE>01142013</DATE> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <DATE>01142013</DATE> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    </CHANGES> 
</PRESOL> 
<FAIROPP> 
    <DATE>02082013</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> 
    <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    </CHANGES> 
</FAIROPP> 
</NOTICES> 

希望的輸出:

<NOTICES> 
<PRESOL> 
<DATE>01/24/2013</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> 
    <AGENCY><![CDATA[Department of the Interior]]></AGENCY> 
    <OFFICE><![CDATA[Fish and Wildlife Service]]></OFFICE> 
    <LOCATION><![CDATA[CGS-WO]]></LOCATION> 
    <ZIP>97232</ZIP> 
    </MOD> 
</CHANGES> 
</PRESOL> 
<COMBINE> 
<DATE>02/10/2013</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>02/09/2013</DATE> 
<AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
<OFFICE><![CDATA[Military Sealift Command]]></OFFICE> 
<LOCATION><![CDATA[MSC Norfolk]]></LOCATION> 
</COMBINE> 
<COMBINE> 
<DATE>02/09/2013</DATE> 
<AGENCY><![CDATA[Department of Veterans Affairs]]></AGENCY> 
<OFFICE><![CDATA[Grand Junction VAMC)]]></OFFICE> 
<LOCATION><![CDATA[Veterans Affairs Medical Center]]></LOCATION> 
</COMBINE> 
<PRESOL> 
<DATE>12/27/2012</DATE> 
<AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
<OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
<LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
<CHANGES> 
    <MOD> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
    <MOD> 
    <AGENCY><![CDATA[Department of the Air Force]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
</CHANGES> 
</PRESOL> 
<FAIROPP> 
<DATE>02/08/2013</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> 
    <AGENCY><![CDATA[Department of the Navy]]></AGENCY> 
    <OFFICE><![CDATA[Pacific Air Forces]]></OFFICE> 
    <LOCATION><![CDATA[354 CONS - Eielson]]></LOCATION> 
    </MOD> 
</CHANGES> 
</FAIROPP> 
</NOTICES> 
+0

我想你的意思是'DATE [../祖先:: */DATE]'? – 2013-02-17 03:12:04

回答

0

DATE[preceding::DATE]不正確,因爲preceding軸包括作爲當前節點的祖先節點。因此,這將匹配整個文檔中除第一個日期之外的全部日期。你想說什麼是「當前日期元素的任何父也有一個日期元素」:

<xsl:template match="DATE[../ancestor::*/DATE]"/> 

..是確保我們不匹配上下文節點(當前DATE元素是看到如果它的祖先有任何一個DATE元素)。

順便說一句,你創建一個新元素的方法是可怕的。用這個代替:

<xsl:template match="DATE"> 
    <xsl:element name="{name()}"> 
     <xsl:value-of select="concat(substring(., 1, 2), '/', substring(., 3, 2), '/', substring(., 5, 4))"/> 
    </xsl:element> 
</xsl:template> 

雖然在你的情況下,它甚至不是必要的 - 只要有模板直接文本節點匹配:

<xsl:template match="DATE/text()"> 
    <xsl:value-of select="concat(substring(., 1, 2), '/', substring(., 3, 2), '/', substring(., 5, 4))"/> 
</xsl:template> 

最終版本的模板:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

    <xsl:template match="DATE/text()"> 
     <xsl:value-of select="concat(substring(., 1, 2), '/', substring(., 3, 2), '/', substring(., 5, 4))"/> 
    </xsl:template> 

    <xsl:template match="DATE[../ancestor::*/DATE]"/> 

</xsl:stylesheet> 
+0

工作就像一個魅力。感謝您的建議並花時間解釋。 – 2013-02-17 04:23:26