XSL для анализа и переупорядочения узлов XML - PullRequest
0 голосов
/ 10 мая 2019

Мне нужна помощь в создании таблицы стилей XSL для анализа данных и изменения порядка на основе значений в определенных узлах.Мой оригинальный XML экспортируется программой реестра в нежелательной структуре, которая вызывает проблемы при преобразовании в JSON.

Это список отдела пожарной охраны, который будет преобразован в JSON для обработки досками состояния станции.Я пытаюсь отформатировать XML, чтобы при преобразовании в JSON каждая станция имела список экипажей.Я попытался создать XSL без успеха.У меня нулевой фон в XSL (Fire Fighter).

Раздел исходного XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
    <Date>2019-05-07-07:00</Date>
    <Headers></Headers>
    <Records>
        <Record>
            <RscPayrollIDCh>12345678</RscPayrollIDCh>
            <RscEmployeeIDCh>12345678</RscEmployeeIDCh>
            <RscMasterNameCh>Smith, Mike A.</RscMasterNameCh>
            <InstitutionAbrvCh>SPL</InstitutionAbrvCh>
            <AgencyAbrvCh>SPFD</AgencyAbrvCh>
            <RegionAbrvCh>OPS</RegionAbrvCh>
            <StationAbrvCh>B19</StationAbrvCh>
            <PUnitAbrvCh>BAT19</PUnitAbrvCh>
            <PosJobAbrvCh>BC-S</PosJobAbrvCh>
        </Record>
        <Record>
            <RscPayrollIDCh>12345</RscPayrollIDCh>
            <RscEmployeeIDCh>12345</RscEmployeeIDCh>
            <RscMasterNameCh>Smith, John A.</RscMasterNameCh>
            <InstitutionAbrvCh>SPL</InstitutionAbrvCh>
            <AgencyAbrvCh>SPFD</AgencyAbrvCh>
            <RegionAbrvCh>OPS</RegionAbrvCh>
            <StationAbrvCh>S15</StationAbrvCh>
            <PUnitAbrvCh>E15</PUnitAbrvCh>
            <PosJobAbrvCh>CAPT</PosJobAbrvCh>
        </Record>
        <Record>
            <RscPayrollIDCh>123456</RscPayrollIDCh>
            <RscEmployeeIDCh>123456</RscEmployeeIDCh>
            <RscMasterNameCh>Smith, Bob R.</RscMasterNameCh>
            <InstitutionAbrvCh>SPL</InstitutionAbrvCh>
            <AgencyAbrvCh>SPFD</AgencyAbrvCh>
            <RegionAbrvCh>OPS</RegionAbrvCh>
            <StationAbrvCh>S15</StationAbrvCh>
            <PUnitAbrvCh>E15</PUnitAbrvCh>
            <PosJobAbrvCh>ENG</PosJobAbrvCh>
        </Record>
    </Records>
</Data>

Я хотел бы отформатировать XML так, чтобы он выглядел примерно так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
    <Date>2019-05-07-07:00</Date>
    <Headers></Headers>
    <Records>
        <Record>
            <StationAbrvCh>B19</StationAbrvCh>
                <RscMasterNameCh>Smith, Mike A.</RscMasterNameCh>
        </Record>
        <Record>
            <StationAbrvCh>S15</StationAbrvCh>
                <RscMasterNameCh>Smith, John A.</RscMasterNameCh>
                <RscMasterNameCh>Smith, Bob R.</RscMasterNameCh>
        </Record>
    </Records>

Я бы хотел, чтобы в моем списке были перечислены все члены экипажа на Станции, на которые они назначены на этот день.

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

Если вы используете XSLT 1.0 , мюнхенская группировка - это лучший подход для достижения этой цели, как показано ниже:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" />
<xsl:key name="groups" match="/Data/Records/Record" use="StationAbrvCh" />

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="/Data/Records">
    <xsl:copy>
        <xsl:for-each select="Record[generate-id() = generate-id(key('groups', StationAbrvCh)[1])]">
            <xsl:copy>
                <StationAbrvCh><xsl:value-of select="StationAbrvCh" /></StationAbrvCh>
                <xsl:for-each select="key('groups', StationAbrvCh)">
                    <RscMasterNameCh><xsl:value-of select="RscMasterNameCh" /></RscMasterNameCh>
                </xsl:for-each>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

См. Демонстрацию здесь: https://xsltfiddle.liberty -development.net / pPzifpM

0 голосов
/ 10 мая 2019

Используя XSLT 2.0 , это довольно просто.

В шаблонной обработке Records, вы должны использовать for-each-group выбрав Record элементов и сгруппировав их по StationAbrvCh.

В каждой группе вы должны:

  • Создать элемент StationAbrvCh, заполненный текущим ключом группировки (также StationAbrvCh).
  • Выполнить цикл for-each для текущей группы, скопировав на выход ток RscMasterNameCh.

Скрипт должен также содержать шаблон идентификации .

Ниже приведен пример сценария:

<?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" indent="yes"/>

  <xsl:template match="Records">
    <xsl:copy>
      <xsl:for-each-group select="Record" group-by="StationAbrvCh">
        <xsl:copy>
          <StationAbrvCh><xsl:value-of select="current-grouping-key()"/></StationAbrvCh>
          <xsl:for-each select="current-group()">
            <xsl:sequence select="RscMasterNameCh"/>
          </xsl:for-each>
        </xsl:copy>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Может быть, чтобы полностью понять каждую деталь вышеупомянутого решения, Вам следует поискать в Интернете описание for-each-group и связанные с ними функции (current-grouping-key() и current-group).

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