XSLT: Json в заданный xml формат - PullRequest
1 голос
/ 13 февраля 2020

Проблема: у меня есть заданный JSON вывод, и мне нужно преобразовать его в xml с заданным форматом, чтобы использовать его для другого ввода.

Документ JSON: отчет. json

 {
  "Diagnostic Cycle" : "2019-02-13T08:19:44ZZ",
    "01 Tester" : {
      "01 Name"              : "IPTester",
      "02 Operating System"  : "Linux",
      "03 Node Name"         : "tester15",
      "04 Release Level"     : "5.4.7",
      "06 Machine"           : "i686",
      "07 Domain Name"       : "(none)" 
    } 
,
    "02 Device Name" : 
{

      "SampleECU":
      {
      "01 Diagnostic"        : "OK",
      "02 CAN Id"            : "(none)",
      "02 DoIP Id"           : "00FFh 124Ah 85B1h",
      "03 VIN original"      : "BZ7282399843",
      "04 VIN current"       : "ERROR 11",
      "05 HW Part No"        : "887895414",
      "06 DTC Status 01"     : 1,
      "10 Hardware Year"     : 2020,
      "11 Hardware Week"     : 08,
      "12 Hardware Patch"    : 0,
      "20 Software Year"     : 2020,
      "21 Software Week"     : 08,
      "22 Software Patch"    : 0,
      "30 Bootware"          : "ERROR 11"
    }
}

Как должен выглядеть XML -выход :

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="./My_Stylesheet.xsl"?>
<VehicleReport xsi:schemaLocation="http://www.w3.org/xsd/vdx30 VDX.3.2.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VDXVersion="3.2.1" xmlns="http://www.w3.org/xsd/vdx30">
    <ServiceTool>
        <Name>IPTester</Name>
        <Version>5.4.7</Version>
        <UserID>tester15</UserID>
        <ExecutionTime>2019-02-13T08:19:44ZZ</ExecutionTime>
    </ServiceTool>
    <VehicleInformation>
        <IdentificationNumberValue>BZ7282399843</IdentificationNumberValue>
    </VehicleInformation>
    <ComponentList>
        <Component>
            <ECUShortName>SampleECU</ECUShortName>
            <DiagnosticInfo>
                <DiagnosticInfoValue>1</DiagnosticInfoValue>
            </DiagnosticInfo>
            <SWHWInformation>
                <Software>
                    <Version>
                        <VersionValue>20/08/00</VersionValue>
                    </Version>
                </Software>
                <Hardware>
                    <PartNumber>
                        <PartNumberValue>887895414</PartNumberValue>
                    </PartNumber>
                    <Version>
                        <VersionValue>20/08/00</VersionValue>
                    </Version>
                </Hardware>
            </SWHWInformation>
        </Component>
      </ComponentList>
</VehicleReport>

Я слышал, что должен использовать Saxon XSLT Процессор для XSLT-преобразования, но я не знаю, как (без опыта XSLT).

Два способа, о которых я могу думать:

  1. Первое использование json -to- xml () затем преобразуйте xml с помощью XSLT
  2. Заполните XML напрямую JSON -значениями (предпочтительно потому, что просто)

Но я не знаю, как сделайте и то и другое - учебное пособие по XSLT приветствуется.

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Возможны оба подхода. Мартин дал вам указание на первый подход (используйте json -do c () или parse- json (), чтобы преобразовать JSON в карты и массивы, а затем заполните документ XML, выбрав в эти карты и массивы. Другой подход заключается в преобразовании в «generi c» XML, а затем преобразование generi c XML с использованием правил шаблонов.

Преобразования (будь то XML - to- XML или JSON -to- XML) обычно бывают либо управляемыми вводом, либо управляемыми выводом. В примере, подобном вашему, где структура вывода имеет мало отношения к структуре ввода, вам нужно быть управляемым выводом: то есть таблица стилей примет форму «Сгенерируйте XXX путем извлечения / a / b / c из ввода, затем сгенерируйте YYY путем извлечения / p / q / r из ввода». сильный индикатор для использования стиля решения, выдвинутого Мартином.

Другой стиль, в котором вы конвертируете JSON в generi c XML и затем применяете шаблоны к generi c XML для производства вашего специфика c * 102 6 *, вероятно, больше подходит для «управляемых вводом» преобразований, которые принимают типичную форму «посмотрите, что будет дальше на входе, и в зависимости от того, что вы найдете, сгенерируйте X или Y или Z на выходе».

0 голосов
/ 13 февраля 2020

Чтобы дать вам один пример того, как работать с XPath 3.1 на JSON значениях, которые представлены в модели данных XPath 3.1 в виде карт и массивов, которые являются функциями, которые вы можете вызывать с именем свойства (для карт / объектов) или индекс (для массивов) в качестве аргумента здесь представляет собой простой код XQuery 3.1, который непосредственно заполняет ваш XML (я поместил в выражения XPath только несколько значений, остальные вы должны заполнить):

<VehicleReport xsi:schemaLocation="http://www.w3.org/xsd/vdx30 VDX.3.2.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VDXVersion="3.2.1" xmlns="http://www.w3.org/xsd/vdx30">
    <ServiceTool>
        <Name>{.("01 Tester")("01 Name")}</Name>
        <Version>{.("01 Tester")("04 Release Level")}</Version>
        <UserID>{.("01 Tester")("03 Node Name")}</UserID>
        <ExecutionTime>{.("Diagnostic Cycle")}</ExecutionTime>
    </ServiceTool>
    <VehicleInformation>
        <IdentificationNumberValue>{.("02 Device Name")("SampleECU")("03 VIN original")}</IdentificationNumberValue>
    </VehicleInformation>
    <ComponentList>
        <Component>
            <ECUShortName>SampleECU</ECUShortName>
            <DiagnosticInfo>
                <DiagnosticInfoValue>1</DiagnosticInfoValue>
            </DiagnosticInfo>
            <SWHWInformation>
                <Software>
                    <Version>
                        <VersionValue>20/08/00</VersionValue>
                    </Version>
                </Software>
                <Hardware>
                    <PartNumber>
                        <PartNumberValue>887895414</PartNumberValue>
                    </PartNumber>
                    <Version>
                        <VersionValue>20/08/00</VersionValue>
                    </Version>
                </Hardware>
            </SWHWInformation>
        </Component>
      </ComponentList>
</VehicleReport>

Предполагается, что JSON является действительным JSON подобно

{
  "Diagnostic Cycle" : "2019-02-13T08:19:44ZZ",
    "01 Tester" : {
      "01 Name"              : "IPTester",
      "02 Operating System"  : "Linux",
      "03 Node Name"         : "tester15",
      "04 Release Level"     : "5.4.7",
      "06 Machine"           : "i686",
      "07 Domain Name"       : "(none)" 
    } 
,
    "02 Device Name" : 
{

      "SampleECU":
      {
      "01 Diagnostic"        : "OK",
      "02 CAN Id"            : "(none)",
      "02 DoIP Id"           : "00FFh 124Ah 85B1h",
      "03 VIN original"      : "BZ7282399843",
      "04 VIN current"       : "ERROR 11",
      "05 HW Part No"        : "887895414",
      "06 DTC Status 01"     : 1,
      "10 Hardware Year"     : 2020,
      "11 Hardware Week"     : 8,
      "12 Hardware Patch"    : 0,
      "20 Software Year"     : 2020,
      "21 Software Week"     : 8,
      "22 Software Patch"    : 0,
      "30 Bootware"          : "ERROR 11"
    }
}
}

и предоставляется в XQuery как элемент контекста, например, с declare context item := json-doc('file.json');.

Saxon 9 поддерживает XQuery 3.1 так же, как и XSLT 3, поэтому, если у вас есть простой XML документ, который вы хотите заполнить, использовать XQuery немного проще, чем XSLT, поскольку шаблонов для шаблона нет.

Онлайн пример: https://xqueryfiddle.liberty-development.net/bFDbxkV.

Итак, основные вопросы, которые необходимо изучить, это понять, что JSON объект { "foo" : 1, "bar": "value" } представлен в виде карты, которая также является функцией вы можете позвоните с именем свойства (например, .("foo") или .("bar")), чтобы выбрать свойство. Для ваших JSON имен свойств, содержащих пробелы, кажется, что путь к go, для простого примера, который я показал, достаточно было бы использовать ?foo или ?bar.

...