XML в CSV - некоторые узлы повторяются, а иногда нет - Java / Groovy / XSLT - PullRequest
0 голосов
/ 21 апреля 2020

Я хотел преобразовать xml файл в csv, некоторые подузлы могут повторяться или не повторяться под родительским узлом, если подузел повторяется, тогда это должна быть отдельная строка в выходном CSV-файле.

<Person>
    <Person>
      <personalInfoNav>
        <PerPersonal>
          <salutationNav>
            <PicklistOption>
              <externalCode>MR</externalCode>
            </PicklistOption>
          </salutationNav>
          <lastName>Test Last Name</lastName>
          <firstName>Test First Name</firstName>
          <gender>M</gender>
          <middleName>Test Middle</middleName>
          <preferredName>Test Name</preferredName>
        </PerPersonal>
      </personalInfoNav>
      <nationalIdNav/>
      <personIdExternal>155999</personIdExternal>
      <dateOfBirth>1982-02-01T00:00:00.000</dateOfBirth>
      <employmentNav>
        <EmpEmployment>
          <compInfoNav>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>120000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-02-01T00:00:00.000</startDate>
            </EmpCompensation>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>132000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-03-25T00:00:00.000</startDate>
            </EmpCompensation>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>138000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-03-31T00:00:00.000</startDate>
            </EmpCompensation>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>144000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-04-10T00:00:00.000</startDate>
            </EmpCompensation>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>150000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-04-20T00:00:00.000</startDate>
            </EmpCompensation>
            <EmpCompensation>
              <empCompensationGroupSumCalculatedNav>
                <EmpCompensationGroupSumCalculated>
                  <amount>162000.0</amount>
                </EmpCompensationGroupSumCalculated>
              </empCompensationGroupSumCalculatedNav>
              <startDate>2020-06-22T00:00:00.000</startDate>
            </EmpCompensation>
          </compInfoNav>
         <jobInfoNav>
            <EmpJob>
              <costCenter>XS000001</costCenter>
              <standardHours>35.0</standardHours>
              <jobTitle>HR Manager</jobTitle>
              <positionNav>
                <Position>
                  <code>37777</code>
                </Position>
              </positionNav>
              <fte>0.88</fte>
              <startDate>2020-02-01T00:00:00.000</startDate>
            </EmpJob>
            <EmpJob>
              <costCenter>COST0001</costCenter>
              <standardHours>15.0</standardHours>
              <jobTitle>HR Manager</jobTitle>
              <positionNav>
                <Position>
                  <code>37777</code>
                </Position>
              </positionNav>
              <fte>0.38</fte>
              <startDate>2020-03-05T00:00:00.000</startDate>
            </EmpJob>
          </jobInfoNav>
        </EmpEmployment>
      </employmentNav>
    </Person>
  </Person>

Ниже приведен желаемый результат. Я пробовал в javascript что-то не хватает или я совершенно не прав.

введите описание изображения здесь

1 Ответ

0 голосов
/ 21 апреля 2020

Я не собираюсь писать ваш код для вас - только для того, чтобы наметить, как вы должны подходить к этому с помощью XSLT.

Цель состоит в том, чтобы создать строку для каждого EmpCompensation с общими данными из раздела personalInfoNav и из последнего раздела EmpJob, чья дата начала раньше или в дату начала текущего EmpCompensation.

Предполагается, что элементы EmpJob перечислены в хронологическом порядке.
Предполагается, что ваш процессор поддерживает XSLT 2.0.

Следующая таблица стилей:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/Person"> 
    <!-- header -->
    <xsl:text>PERNR,Last Name,Cost Center,Job StartDate,Salary EffDate,Annual Salary&#10;</xsl:text>
    <xsl:for-each select="Person">
        <xsl:variable name="personal-data">
            <xsl:value-of select="personIdExternal"/>
            <xsl:text>,</xsl:text>          
            <xsl:value-of select="personalInfoNav/PerPersonal/lastName"/>
            <xsl:text>,</xsl:text>          
        </xsl:variable>
        <xsl:variable name="jobs" select="employmentNav/EmpEmployment/jobInfoNav/EmpJob"/>
        <!-- data rows -->
        <xsl:for-each select="employmentNav/EmpEmployment/compInfoNav/EmpCompensation">
            <!-- personal data -->
            <xsl:copy-of select="$personal-data"/>
            <!-- job data -->
            <xsl:variable name="job" select="$jobs[startDate le current()/startDate][last()]"/>
            <xsl:value-of select="$job/costCenter"/>
            <xsl:text>,</xsl:text>          
            <xsl:value-of select="$job/startDate"/>
            <xsl:text>,</xsl:text>          
            <!-- salary data -->
            <xsl:value-of select="startDate"/>
            <xsl:text>,</xsl:text>          
            <xsl:value-of select="empCompensationGroupSumCalculatedNav/EmpCompensationGroupSumCalculated/amount"/>
            <xsl:text>&#10;</xsl:text>          
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

при применении к вашему примеру ввода вернет:

Результат

PERNR,Last Name,Cost Center,Job StartDate,Salary EffDate,Annual Salary
155999,Test Last Name,XS000001,2020-02-01T00:00:00.000,2020-02-01T00:00:00.000,120000.0
155999,Test Last Name,COST0001,2020-03-05T00:00:00.000,2020-03-25T00:00:00.000,132000.0
155999,Test Last Name,COST0001,2020-03-05T00:00:00.000,2020-03-31T00:00:00.000,138000.0
155999,Test Last Name,COST0001,2020-03-05T00:00:00.000,2020-04-10T00:00:00.000,144000.0
155999,Test Last Name,COST0001,2020-03-05T00:00:00.000,2020-04-20T00:00:00.000,150000.0
155999,Test Last Name,COST0001,2020-03-05T00:00:00.000,2020-06-22T00:00:00.000,162000.0

Демо : https://xsltfiddle.liberty-development.net/6pS26mM

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...