这是我需要使用XSLT 2.0转换的输入XML
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<id>1234</id>
<loc>New York</loc>
<Days>1</Days>
<StartDate>2019-01-26</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<Batch>A</Batch>
<Days>3</Days>
<Units>2</Units>
<StartDate>2019-02-01</StartDate>
</Worker>
</Workers>
电流输出
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<id>1234</id>
<loc>New York</loc>
<Days>1</Days>
<StartDate>2019-01-26</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>1</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-02</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>2</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-03</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>3</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-04</StartDate>
</Worker>
</Workers>
预期输出
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<id>1234</id>
<loc>New York</loc>
<Days>1</Days>
<StartDate>2019-01-26</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>1</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-01</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>2</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-02/StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>3</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-03</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>1</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-01</StartDate>
</Worker>
<Worker>
<id>2345</id>
<loc>Boston</loc>
<RecordNumber>2</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>2019-02-02/StartDate>
</Worker>
</Workers>
我的要求是
a。)如果子节点中不存在元素<Batch>
,则应按照XML中出现的方式复制该子节点。在上面的XML中,应该复制第一个辅助子节点,因为它没有包含<Batch>
元素。
b。)如果子节点中存在元素<Batch>
,则需要根据以下两个条件将该子节点拆分为多个子节点
1。)子节点的创建次数需要与元素<Days>
的值一样多。在这种情况下,<Days>
的值为3,因此需要创建3个子节点,并且每个子节点应将<StartDate>
递增1并创建一个新元素<RecordNumber>
应该包含该循环的值。
2。)再次需要根据元素<Units>
的值拆分子节点。在上述XML中,<Units>
为2,因此需要创建两次子节点,并且每次创建并创建一个新元素<StartDate>
时,<RecordNumber>
都需要增加一个。保持那个循环的值
当前的XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Workers/Worker[exists(Batch)]">
<xsl:variable name="start" select="1"/>
<xsl:variable name="counter" select="Days"/>
<xsl:variable name="Records" select="."/>
<xsl:for-each select="$start to $counter">
<xsl:apply-templates select="$Records" mode="replicate">
<xsl:with-param name="data" select="."/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="Workers/Worker" mode="replicate">
<xsl:param name="data"/>
<Worker>
<id>
<xsl:value-of select="id"/>
</id>
<loc>
<xsl:value-of select="loc"/>
</loc>
<RecordNumber>
<xsl:value-of select="$data"/>
</RecordNumber>
<WorkerDays>1</WorkerDays>
<StartDate>
<xsl:value-of select="xs:date(StartDate) + xs:dayTimeDuration('P1D') * $data"/>
</StartDate>
</Worker>
</xsl:template>
</xsl:stylesheet>
问题:
<StartDate>
的值有误-似乎缺少实际的<StartDate>
XSLT根本不拆分子节点。
<Worker>
子节点应该在预期输出中出现6次,而现在我只有4次。
有人可以帮我解决此问题吗?
谢谢
答案 0 :(得分:1)
从您的预期输出中,我看到您需要按顺序依次2个循环:
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" CONFIG_H_IN)
string(CONFIGURE "${CONFIG_H_IN}" CONFIG_H_TMP)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.h" CONTENT "${CONFIG_H_TMP}")
次,Days
次,都是连续的日期,从输入日期开始。
请注意,在Units
循环中,上下文项已更改,因此在
在两个for-each
循环的情况下,上下文项是的当前编号
执行,格式为for-each
。
这是在每个循环中调用select
模板时的原因,
Worker
参数以点的形式给出,而 currElem 是
只是为其调用了dayNo
模板的元素。
就输出Worker[Batch]
而言,StartDate
必须
被添加dayTimeDuration
次。
另一个有用的添加/更改是:
$dayNo - 1
开头,导致“更好”
输出缩进。<xsl:strip-space elements="*"/>
-较短的形式,用于将源元素复制到输出。
还需要注意的是,它运行更快,消耗很多
更少的内存。<xsl:sequence .../>
的变量。恕我直言,这个名字是“太笼统”,
所以我将其更改为data
(当前元素)。因此整个脚本如下所示:
currElem
有关工作示例,请参见http://xsltransform.net/asnmyP/1
第一个版本位于http://xsltransform.net/asnmyP下(如果需要的话) 进行比较)。