#xml #xslt
Вопрос:
Я пытаюсь преобразовать следующий xml таким образом, чтобы:
- текущие входные данные копируются для каждой уникальной даты начала в xml (и группируются по этой дате начала).
- каждая созданная структура CompoundEmployee содержит только те родительские узлы, для которых дата начала группы находится в диапазоне ее дочерних дат начала и окончания.
Ввод:
<queryCompoundEmployeeResponse>
<CompoundEmployee>
<employment_information>
<start_date>2021-11-01</start_date>
<end_date>9999-12-31</end_date>
<job_information>
<start_date>2021-12-01</start_date>
<end_date>9999-12-31</end_date>
</job_information>
<job_information>
<start_date>2021-11-01</start_date>
<end_date>2021-11-30</end_date>
</job_information>
</employment_information>
<employment_information>
<start_date>2021-03-01</start_date>
<end_date>2021-10-31</end_date>
<job_information>
<start_date>2021-05-01</start_date>
<end_date>2021-10-31</end_date>
</job_information>
<job_information>
<start_date>2021-03-01</start_date>
<end_date>2021-04-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</queryCompoundEmployeeResponse>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="//CompoundEmployee">
<queryCompoundEmployeeResponse>
<xsl:for-each-group select="." group-by="//start_date">
<xsl:sort select="current-grouping-key()"/>
<start_date date="{current-grouping-key()}">
<xsl:for-each select="current-group()">
<CompoundEmployee>
<xsl:copy-of select="./*[start_date amp;<= current-grouping-key() and end_date amp;> current-grouping-key()]"/>
</CompoundEmployee>
</xsl:for-each>
</start_date>
</xsl:for-each-group>
</queryCompoundEmployeeResponse>
</xsl:template>
</xsl:stylesheet>
Текущий вывод, который генерируется, близок к тому, что я хочу: каждая группа содержит только один узел информации о занятости, где дата начала группы находится в диапазоне даты начала и окончания информации о занятости. Однако то же самое не происходит для узлов job_information в employment_information:
<queryCompoundEmployeeResponse>
<start_date date="2021-03-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-03-01</start_date>
<end_date>2021-10-31</end_date>
<job_information>
<start_date>2021-05-01</start_date>
<end_date>2021-10-31</end_date>
</job_information>
<job_information>
<start_date>2021-03-01</start_date>
<end_date>2021-04-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-05-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-03-01</start_date>
<end_date>2021-10-31</end_date>
<job_information>
<start_date>2021-05-01</start_date>
<end_date>2021-10-31</end_date>
</job_information>
<job_information>
<start_date>2021-03-01</start_date>
<end_date>2021-04-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-11-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-11-01</start_date>
<end_date>9999-12-31</end_date>
<job_information>
<start_date>2021-12-01</start_date>
<end_date>9999-12-31</end_date>
</job_information>
<job_information>
<start_date>2021-11-01</start_date>
<end_date>2021-11-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-12-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-11-01</start_date>
<end_date>9999-12-31</end_date>
<job_information>
<start_date>2021-12-01</start_date>
<end_date>9999-12-31</end_date>
</job_information>
<job_information>
<start_date>2021-11-01</start_date>
<end_date>2021-11-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
</queryCompoundEmployeeResponse>
How do I need to change my XSLT so that each employment_information node contains only the one job_information node where the group startdate is within its start-enddate range? It’s possible for the XML to contain deeper levels of nesting and differently named nodes (each containing a start and enddate), so I’d like to avoid explicit references to «employment_information» and «job_information».
Expected output:
<queryCompoundEmployeeResponse>
<start_date date="2021-03-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-03-01</start_date>
<end_date>2021-10-31</end_date>
<job_information>
<start_date>2021-03-01</start_date>
<end_date>2021-04-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-05-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-03-01</start_date>
<end_date>2021-10-31</end_date>
<job_information>
<start_date>2021-05-01</start_date>
<end_date>2021-10-31</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-11-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-11-01</start_date>
<end_date>9999-12-31</end_date>
<job_information>
<start_date>2021-11-01</start_date>
<end_date>2021-11-30</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
<start_date date="2021-12-01">
<CompoundEmployee>
<employment_information>
<start_date>2021-11-01</start_date>
<end_date>9999-12-31</end_date>
<job_information>
<start_date>2021-12-01</start_date>
<end_date>9999-12-31</end_date>
</job_information>
</employment_information>
</CompoundEmployee>
</start_date>
</queryCompoundEmployeeResponse>