Конвертируйте JSON в XML с помощью XSLT 3.0 - экранируйте амперсанд в ключе элемента - PullRequest
0 голосов
/ 08 января 2019

Используя XSLT, мы хотим преобразовать JSON в XML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs math" version="3.0">
<xsl:output indent="yes" />
    <xsl:template match="data">
        <xsl:copy-of select="json-to-xml(.)" />
    </xsl:template>
</xsl:stylesheet>

У нас есть вывод JSON из Microsoft Dynamics 365, который мы хотим преобразовать в XML.

JSON:

<data>
{
    "@odata.context": "https:\/\/xxx.api.crm4.dynamics.com\/api\/data\/v9.0\/$metadata#msdyn_bookingjournals(msdyn_journaltype,msdyn_name,msdyn_starttime,msdyn_endtime,msdyn_duration,foc_sapstatisticalkeyfigurecod,statecode)",
    "value": [
    {
        "@odata.etag": "W\/\"3935842\"",
        "msdyn_journaltype@OData.Community.Display.V1.FormattedValue": "Travel",
        "msdyn_journaltype": 690970002,
        "msdyn_name": "Wartung  - Wartung - 101 Innener Verkehrsring\/D\u00fcsseldorferstr ",
        "msdyn_starttime@OData.Community.Display.V1.FormattedValue": "13.11.2018 13:11",
        "msdyn_starttime": "2018-11-13T13:11:58Z",
        "msdyn_endtime@OData.Community.Display.V1.FormattedValue": "13.11.2018 13:15",
        "msdyn_endtime": "2018-11-13T13:15:58Z",
        "msdyn_duration@OData.Community.Display.V1.FormattedValue": "4",
        "msdyn_duration": 4,
        "foc_sapstatisticalkeyfigurecod": "",
        "statecode@OData.Community.Display.V1.FormattedValue": "Active",
        "statecode": 0,
        "msdyn_bookingjournalid": "cb6d62ee-49e7-e811-a958-000d3a29fea4"
    },
    {
        "@odata.etag": "W\/\"3935846\"",
        "msdyn_journaltype@OData.Community.Display.V1.FormattedValue": "Working Hours",
        "msdyn_journaltype": 690970000,
        "msdyn_name": "Wartung  - Wartung - 101 Innener Verkehrsring\/D\u00fcsseldorferstr ",
        "msdyn_starttime@OData.Community.Display.V1.FormattedValue": "13.11.2018 13:15",
        "msdyn_starttime": "2018-11-13T13:15:58Z",
        "msdyn_endtime@OData.Community.Display.V1.FormattedValue": "13.11.2018 13:20",
        "msdyn_endtime": "2018-11-13T13:20:57Z",
        "msdyn_duration@OData.Community.Display.V1.FormattedValue": "4",
        "msdyn_duration": 4,
        "foc_sapstatisticalkeyfigurecod": "",
        "statecode@OData.Community.Display.V1.FormattedValue": "Active",
        "statecode": 0,
        "msdyn_bookingjournalid": "fe6d62ee-49e7-e811-a958-000d3a29fea4"
    }
    ],
    "@odata.nextLink": "https:\/\/xxx.api.crm4.dynamics.com\/api\/data\/v9.0\/bookableresourcebookings(b0fe5834-45e7-e811-a958-000d3a29fb7a)\/msdyn_bookableresourcebooking_msdyn_bookingjournal_Booking?$select=msdyn_journaltype,msdyn_name,msdyn_starttime,msdyn_endtime,msdyn_duration,foc_sapstatisticalkeyfigurecod,statecode&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%2520parentEntityId%253d%2522b0fe5834-45e7-e811-a958-000d3a29fb7a%2522%2520parentAttributeName%253d%2522msdyn_booking%2522%2520parentEntityObjectTypeCode%253d%25221145%2522%253e%253cmsdyn_bookingjournalid%2520last%253d%2522%257bFE6D62EE-49E7-E811-A958-000D3A29FEA4%257d%2522%2520first%253d%2522%257bCB6D62EE-49E7-E811-A958-000D3A29FEA4%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20\/%3E"
}
</data>

При тестировании этого XSLT-преобразования на https://www.freeformatter.com/xsl-transformer.html, я получаю следующую ошибку

Unable to generate the XML document using the provided XML/XSL input.
org.xml.sax.SAXParseException; lineNumber: 38; columnNumber: 325;
The entity name must immediately follow the '&' in the entity reference.
You most likely forgot to escape '&' into '&amp;'

Очевидно, это связано с неэкранированным амперсандом после кода состояния в

"@odata.nextLink":"...foc_sapstatisticalkeyfigurecod,statecode&$skiptoken="

Преобразование работает нормально при замене & на экранированное значение:

"@odata.nextLink":"...foc_sapstatisticalkeyfigurecod,statecode&amp;$skiptoken="

Есть ли способ избежать запрещенных символов XML при преобразовании XSLT из JSON в XML?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Нет, если у вас нет правильно сформированного XML, вы мало что можете сделать с XSLT.

Сначала восстановите XML, затем выполните обработку XSLT. Варианты исправления XML представлены в другом ответе .

0 голосов
/ 08 января 2019

XSLT версии 4.0 не существует.

На каком-то этапе цепочки обработки вы завернули текст JSON (или JSON-подобный) в теги <data>...</data>, не заботясь о том, чтобы специальные символы в тексте JSON были правильно экранированы.

На самом деле, упаковка JSON в оболочку XML не обязательна. Вы можете прочитать входной файл JSON напрямую, используя json-to-xml(unparsed-text('input.json')). Затем вы обычно начинаете преобразование с выполнения именованного шаблона (называемого, скажем, «main» или «xsl: initial-template»), а не путем предоставления исходного XML-документа и использования match="/".

...