【发布时间】:2020-05-23 02:08:34
【问题描述】:
我的 XSLT 知识还很初级,但我已经了解了这么多。给定一组节点,我可以应用一个模板来选择节点,从而改变日期的格式。像这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes"/>
<xsl:template match="/Data">
<xsl:apply-templates select="Worker"/>
</xsl:template>
<xsl:template match="Worker">
<xsl:value-of select="LINE_NO"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="WD_BATCH_ID"/>
<xsl:text>,</xsl:text>
<xsl:apply-templates select="./DATE_WORKED"/>
<xsl:text>,</xsl:text>
<xsl:apply-templates select="./EFFECTIVE_DATE"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="HOURS"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="Worker/node()">
<xsl:value-of select="concat('20',substring-after(substring-after(.,'-'),'-'))"/>
<xsl:text>-</xsl:text>
<xsl:choose>
<xsl:when test="contains(., 'JAN')">01</xsl:when>
<xsl:when test="contains(., 'FEB')">02</xsl:when>
<xsl:when test="contains(., 'MAR')">03</xsl:when>
<xsl:when test="contains(., 'APR')">04</xsl:when>
<xsl:when test="contains(., 'MAY')">05</xsl:when>
<xsl:when test="contains(., 'JUN')">06</xsl:when>
<xsl:when test="contains(., 'JUL')">07</xsl:when>
<xsl:when test="contains(., 'AUG')">08</xsl:when>
<xsl:when test="contains(., 'SEP')">09</xsl:when>
<xsl:when test="contains(., 'OCT')">10</xsl:when>
<xsl:when test="contains(., 'NOV')">11</xsl:when>
<xsl:when test="contains(., 'DEC')">12</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring-before(.,'-')"/>
</xsl:template>
</xsl:stylesheet>
这个 XSLT 代表了我对 XSLT 理解的一点突破,所以我为它感到有点自豪 ;-) 我喜欢我可以将日期格式模板应用于 Worker 的任何直系子级这一事实,我所要做的就是命名子节点。这个恰好生成一个 CSV 文件。
我想做类似的事情,但复制 XML,并且不必指定要复制的每个节点,只需指定我想要此日期格式模板的节点。
是否有一种方便的方法可以不可知地说“复制此 XML 中的任何给定节点,如果节点名为 DATE_WORKED 在复制时应用此模板?或者,如果 XSL 可以通过某种方式神奇地识别任何日期并且只是格式化它......那会很酷。
我可以访问 XSL 1、2 和 3.0
我的想法是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="//DATE_WORKED" />
</xsl:copy>
</xsl:template>
<xsl:template match="Worker/node()">
<xsl:value-of select="concat('20',substring-after(substring-after(.,'-'),'-'))"/>
<xsl:text>-</xsl:text>
<xsl:choose>
<xsl:when test="contains(., 'JAN')">01</xsl:when>
<xsl:when test="contains(., 'FEB')">02</xsl:when>
<xsl:when test="contains(., 'MAR')">03</xsl:when>
<xsl:when test="contains(., 'APR')">04</xsl:when>
<xsl:when test="contains(., 'MAY')">05</xsl:when>
<xsl:when test="contains(., 'JUN')">06</xsl:when>
<xsl:when test="contains(., 'JUL')">07</xsl:when>
<xsl:when test="contains(., 'AUG')">08</xsl:when>
<xsl:when test="contains(., 'SEP')">09</xsl:when>
<xsl:when test="contains(., 'OCT')">10</xsl:when>
<xsl:when test="contains(., 'NOV')">11</xsl:when>
<xsl:when test="contains(., 'DEC')">12</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring-before(.,'-')"/>
</xsl:template>
</xsl:stylesheet>
...不复制节点,仅在“DATE_WORKED”节点上运行。
是的,我找到了这个答案:Using XSLT to copy all nodes in XML, with support for special cases 但它需要为我要格式化的每个节点制作一个重复的模板。
我正在使用如下所示的 XML:
<?xml version='1.0' encoding='UTF-8'?>
<Data>
<Worker>
<LINE_NO>LineNo</LINE_NO>
<INT_ID>IntId</INT_ID>
<WD_BATCH_ID>WdBatchId</WD_BATCH_ID>
<WD_PAY_INPUT_ID>WdPayInputId</WD_PAY_INPUT_ID>
<DATE_WORKED>DateWorked</DATE_WORKED>
<EMPLOYEE_ID>EmployeeId</EMPLOYEE_ID>
<WEEK_END_DATE>WeekEndDate</WEEK_END_DATE>
<EFFECTIVE_DATE>EffectiveDate</EFFECTIVE_DATE>
<HOURS>Hours</HOURS>
<PAY_COMPONENT>PayComponent</PAY_COMPONENT>
<TK_COMMENTS>TkComments</TK_COMMENTS>
<SS_REQUEST_ID>SsRequestId</SS_REQUEST_ID>
<REQUEST_ID>RequestId</REQUEST_ID>
<PROCESS_STATUS>ProcessStatus</PROCESS_STATUS>
</Worker>
<Worker>
<LINE_NO>0001</LINE_NO>
<INT_ID>248697</INT_ID>
<WD_BATCH_ID>kns_timeoff20191215_7_78593974</WD_BATCH_ID>
<WD_PAY_INPUT_ID>248696</WD_PAY_INPUT_ID>
<DATE_WORKED>25-NOV-19</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>01-DEC-19</WEEK_END_DATE>
<EFFECTIVE_DATE>15-DEC-19</EFFECTIVE_DATE>
<HOURS>9</HOURS>
<PAY_COMPONENT>Military AD</PAY_COMPONENT>
<TK_COMMENTS>.</TK_COMMENTS>
<SS_REQUEST_ID>78593755</SS_REQUEST_ID>
<REQUEST_ID>78593974</REQUEST_ID>
<PROCESS_STATUS>C</PROCESS_STATUS>
</Worker>
<Worker>
<LINE_NO>0002</LINE_NO>
<INT_ID>248701</INT_ID>
<WD_BATCH_ID>kns_timeoff20191215_7_78593974</WD_BATCH_ID>
<WD_PAY_INPUT_ID>248700</WD_PAY_INPUT_ID>
<DATE_WORKED>26-NOV-19</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>01-DEC-19</WEEK_END_DATE>
<EFFECTIVE_DATE>15-DEC-19</EFFECTIVE_DATE>
<HOURS>9</HOURS>
<PAY_COMPONENT>Military AD</PAY_COMPONENT>
<TK_COMMENTS>.</TK_COMMENTS>
<SS_REQUEST_ID>78593755</SS_REQUEST_ID>
<REQUEST_ID>78593974</REQUEST_ID>
<PROCESS_STATUS>C</PROCESS_STATUS>
</Worker>
<Worker>
<LINE_NO>0003</LINE_NO>
<INT_ID>248699</INT_ID>
<WD_BATCH_ID>kns_timeoff20191215_7_78593974</WD_BATCH_ID>
<WD_PAY_INPUT_ID>248698</WD_PAY_INPUT_ID>
<DATE_WORKED>27-NOV-19</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>01-DEC-19</WEEK_END_DATE>
<EFFECTIVE_DATE>15-DEC-19</EFFECTIVE_DATE>
<HOURS>9</HOURS>
<PAY_COMPONENT>Military AD</PAY_COMPONENT>
<TK_COMMENTS>.</TK_COMMENTS>
<SS_REQUEST_ID>78593755</SS_REQUEST_ID>
<REQUEST_ID>78593974</REQUEST_ID>
<PROCESS_STATUS>C</PROCESS_STATUS>
</Worker>
<Worker>
<LINE_NO>0004</LINE_NO>
<INT_ID>1082611</INT_ID>
<WD_BATCH_ID>kns_wd20191215_8_78593974</WD_BATCH_ID>
<WD_PAY_INPUT_ID>WK1.1082611</WD_PAY_INPUT_ID>
<DATE_WORKED>01-DEC-19</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>01-DEC-19</WEEK_END_DATE>
<EFFECTIVE_DATE>15-DEC-19</EFFECTIVE_DATE>
<HOURS>7</HOURS>
<PAY_COMPONENT>EWWHRWK1</PAY_COMPONENT>
<TK_COMMENTS>.</TK_COMMENTS>
<SS_REQUEST_ID>78593755</SS_REQUEST_ID>
<REQUEST_ID>78593974</REQUEST_ID>
<PROCESS_STATUS>C</PROCESS_STATUS>
</Worker>
</Data>
【问题讨论】:
-
您能否提供输入 XML 以制作minimal reproducible example?
-
嗯,部分原因是,传递给它的 XML 应该不是很重要。我可以使用身份转换复制任何 xml,对吗?我希望能够做类似的事情,但支持特殊情况。我已经添加了我正在使用的 XML。
-
明确地说,我希望能够指定任意数量的节点,而不仅仅是一个。