有没有一种简单的方法可以复制 XML 文档,但更改日期节点的格式?
Is there a simple way to copy an XML docuement, but change the format of date nodes?
我的 XSLT 知识还很初级,但我已经了解了这么多。给定一组节点,我可以将模板应用于 select 个节点,这会更改日期格式。像这样:
<?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>
如何将 XSLT 代码更改为
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Remove all space between * elements -->
<xsl:strip-space elements="*" />
<!-- Identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- Except for DATE_WORKED or WEEK_END_DATE or EFFECTIVE_DATE children -->
<xsl:template match="DATE_WORKED | WEEK_END_DATE | EFFECTIVE_DATE">
<xsl:copy>
<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:copy>
</xsl:template>
它的输出(例如)是:
<?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>20--</DATE_WORKED>
<EMPLOYEE_ID>EmployeeId</EMPLOYEE_ID>
<WEEK_END_DATE>20--</WEEK_END_DATE>
<EFFECTIVE_DATE>20--</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>2019-11-25</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-11-26</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-11-27</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-12-01</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>
第一项的输出是错误的,所以你需要做一个例外规则。但其余的确实适合。
此外,在 XSLT-3.0 中,身份模板 可以替换为元素
<xsl:mode on-no-match="shallow-copy" />
为了使其更通用,您可以使用模板匹配规则
<xsl:template match="*[contains(local-name(),'DATE')]">
匹配名称中包含字符串 'DATE'.
的所有元素
补充@zx485的回答,如果你想避免丑xsl:choose
,你可以试试
<xsl:function name="f:month-number" as="xs:integer?">
<xsl:param name="month-abbr" as="xs:string"/>
<xsl:sequence select="index-of(('JAN', 'FEB', 'MAR', ...), $month-abbr)"/>
</xsl:function>
然后使用 format-integer() 将结果格式化为两位数。
我的 XSLT 知识还很初级,但我已经了解了这么多。给定一组节点,我可以将模板应用于 select 个节点,这会更改日期格式。像这样:
<?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>
如何将 XSLT 代码更改为
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Remove all space between * elements -->
<xsl:strip-space elements="*" />
<!-- Identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- Except for DATE_WORKED or WEEK_END_DATE or EFFECTIVE_DATE children -->
<xsl:template match="DATE_WORKED | WEEK_END_DATE | EFFECTIVE_DATE">
<xsl:copy>
<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:copy>
</xsl:template>
它的输出(例如)是:
<?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>20--</DATE_WORKED>
<EMPLOYEE_ID>EmployeeId</EMPLOYEE_ID>
<WEEK_END_DATE>20--</WEEK_END_DATE>
<EFFECTIVE_DATE>20--</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>2019-11-25</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-11-26</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-11-27</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>2019-12-01</DATE_WORKED>
<EMPLOYEE_ID>101877</EMPLOYEE_ID>
<WEEK_END_DATE>2019-12-01</WEEK_END_DATE>
<EFFECTIVE_DATE>2019-12-15</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>
第一项的输出是错误的,所以你需要做一个例外规则。但其余的确实适合。
此外,在 XSLT-3.0 中,身份模板 可以替换为元素
<xsl:mode on-no-match="shallow-copy" />
为了使其更通用,您可以使用模板匹配规则
<xsl:template match="*[contains(local-name(),'DATE')]">
匹配名称中包含字符串 'DATE'.
的所有元素补充@zx485的回答,如果你想避免丑xsl:choose
,你可以试试
<xsl:function name="f:month-number" as="xs:integer?">
<xsl:param name="month-abbr" as="xs:string"/>
<xsl:sequence select="index-of(('JAN', 'FEB', 'MAR', ...), $month-abbr)"/>
</xsl:function>
然后使用 format-integer() 将结果格式化为两位数。