Использование XSLT для преобразования XML в JSON - PullRequest
1 голос
/ 25 сентября 2019

Я хотел бы использовать XSLT для преобразования некоторых XML в JSON.
XML выглядит следующим образом:

<DATA_DS>
    <G_1>
        <ORGANIZATION_NAME>My Company 1</ORGANIZATION_NAME>
        <ORGANIZATIONID>901</ORGANIZATIONID>
        <ITEMNUMBER>20001</ITEMNUMBER>
        <ITEMDESCRIPTION>Item Description 1</ITEMDESCRIPTION>
    </G_1>
    <G_1>
        <ORGANIZATION_NAME>My Company 1</ORGANIZATION_NAME>
        <ORGANIZATIONID>901</ORGANIZATIONID>
        <ITEMNUMBER>20002</ITEMNUMBER>
        <ITEMDESCRIPTION>Item Description 2</ITEMDESCRIPTION>
    </G_1>
    <G_1>
        <ORGANIZATION_NAME>My Company 1</ORGANIZATION_NAME>
        <ORGANIZATIONID>901</ORGANIZATIONID>
        <ITEMNUMBER>20003</ITEMNUMBER>
        <ITEMDESCRIPTION>Item Description 3</ITEMDESCRIPTION>
    </G_1>
</DATA_DS>

Я ожидаю, что JSON будет выглядеть следующим образом:

    [
        {
            "Item_Number":"20001",
            "Item_Description":"Item Description 1"
        },
        {
            "Item_Number":"20002",
            "Item_Description":"Item Description 2"
        },
        {
            "Item_Number":"20003",
            "Item_Description":"Item Description 3"
        }
    ]

Каков рекомендуемый способ сделать это?

Я рассматриваю два подхода:

  1. Попробуйте использовать функцию fn:xml-to-json, как определено в https://www.w3.org/TR/xpath-functions-31/#func-xml-to-json. Но, как я понимаю, входной XML должен следовать определенному формату, определенному в: https://www.w3.org/TR/xpath-functions-31/schema-for-json.xsd. И мне также нужно, чтобы имена полей в выходном JSON были конкретно "Item_Number" и "Item_Description".

  2. Вручную закодируйте символы скобок и скобок, "[", "]", "{" и "}", а также имена полей "Item_Number" и "Item_Description".Затем используйте стандартную функцию для получения списка значений и убедитесь, что любые специальные символы обрабатываются правильно.Например, символ «&» должен обычно отображаться в выводе JSON.

Каков рекомендуемый способ сделать это, или есть лучший способ, который я не рассматривал?

Ответы [ 3 ]

2 голосов
/ 25 сентября 2019

Я бы выбрал первый подход, но начнем с преобразования указанного ввода в формат XML, ожидаемый функцией xml-to-json().Это может быть что-то вроде:

XSLT 3.0

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/G_1">
    <!-- CONVERT INPUT TO XML FOR JSON -->
    <xsl:variable name="xml">
        <array>
            <xsl:for-each-group select="*" group-starting-with="ORGANIZATION_NAME">
                <map>
                    <string key="Item_Number">
                        <xsl:value-of select="current-group()[self::ITEMNUMBER]"/>
                    </string>
                    <string key="Item_Description">
                        <xsl:value-of select="current-group()[self::ITEMDESCRIPTION]"/>
                    </string>
                </map>
            </xsl:for-each-group>
        </array>
    </xsl:variable>
    <!-- OUTPUT -->
    <xsl:value-of select="xml-to-json($xml)"/>
</xsl:template>

</xsl:stylesheet>

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

0 голосов
/ 25 сентября 2019

Для таких простых сопоставлений вы также можете напрямую создавать массивы и карты XPath 3.1, т.е. в этом случае массив карт:

  <xsl:template match="DATA_DS">
      <xsl:sequence select="array { G_1 ! map { 'Item_Number' : string(ITEMNUMBER), 'Item_Description' : string(ITEMDESCRIPTION) } }"/>
  </xsl:template>

Затем сериализовать как JSON с <xsl:output method="json" indent="yes"/>: https://xsltfiddle.liberty -development.net / ejivdGS

Основным недостатком является то, что карты не имеют порядка, поэтому вы не можете контролировать порядок элементов на карте, например, для этого примера и используемой версии Saxon.Item_Description выводится до Item_Number.

Но в целом преобразование в формат для xml-to-json обеспечивает большую гибкость, а также позволяет контролировать порядок, так как функция сохраняет порядок в XML-представлении JSON..

0 голосов
/ 25 сентября 2019

Это результат взятия решения, опубликованного michael.hor257k, и применения его к моему пересмотренному входному XML:

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="text" encoding="UTF-8"/>

    <xsl:template match="/DATA_DS">
        <!-- CONVERT INPUT TO XML FOR JSON -->
        <xsl:variable name="xml">
            <array>
                <xsl:for-each  select="G_1">
                <map>
                    <string key="Item_Number">
                        <xsl:value-of select="ITEMNUMBER"/>
                    </string>
                    <string key="Item_Description">
                        <xsl:value-of select="ITEMDESCRIPTION"/>
                    </string>
                </map>
            </xsl:for-each>
            </array>
        </xsl:variable>
        <!-- OUTPUT -->
         <xsl:value-of select="xml-to-json($xml)"/>
    </xsl:template>

</xsl:stylesheet>

...