Вот мой входной XML, который мне нужно преобразовать с использованием XSLT 2.0
<?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 первый рабочий дочерний узел должен быть скопирован так, как он выглядит в XML, так как в нем нет элемента <Batch>
.
b.) Если элемент <Batch>
присутствует вдочерний узел, этот дочерний узел должен быть разбит на несколько дочерних узлов на основе следующих двух условий
1.) Количество дочерних узлов необходимо создавать столько раз, сколько значение элемента <Days>
.В этом случае <Days>
имеет 3 в качестве значения, поэтому необходимо создать 3 дочерних узла, и каждый из этих дочерних узлов должен увеличить <StartDate>
на единицу и создать новый элемент <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.
Может кто-нибудь помочь мне исправитьвопрос пожалуйста?
Спасибо