преобразование json в XML с помощью XSL

#json #xml #xslt #xslt-3.0

#json #xml #xslt #xslt-3.0

Вопрос:

Мне нужно преобразовать сообщение json в XML. Я создал базовый сценарий преобразования XSL, но в результирующем XML используются теги «map» со значениями json в качестве атрибутов «key».

Есть ли способ использовать значения имен в качестве тегов или мне нужно написать второе преобразование XSL, чтобы получить то, что я хочу?

json:

 <?xml version="1.0"?>
<data>
{ "Policies":   
        {
        "Policy": {                 
               "PolicyNum": "1234",             
               "Customer": "Smith"              
                      },
        "Policy": {                 
               "PolicyNum": "5678",         
               "Customer": "Jones"              
                      }
                 }
}
</data>
 

xsl:

 <?xml version="1.0"?>
<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" omit-xml-declaration="no" />
    <xsl:template match="data">
        <xsl:copy-of select="json-to-xml(.)"/>
    </xsl:template>
</xsl:stylesheet>
 

результирующий XML: (с использованием https://xslttest.appspot.com /)

 <?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <map key="Policies">
      <map key="Policy">
         <string key="PolicyNum">1234</string>
         <string key="Customer">Smith</string>
      </map>
      <map key="Policy">
         <string key="PolicyNum">5678</string>
         <string key="Customer">Jones</string>
      </map>
   </map>
</map>
 

XML, который мне нужен:

    <Policies>
      <Policy>
            <PolicyNum>1234</PolicyNum>
            <Customer>Smith</Customer>
      </Policy>
      <Policy>
            <PolicyNum>5678</PolicyNum>
            <Customer>Jones</Customer>
      </Policy>
   </Policies>
 

Комментарии:

1. Я не вижу JSON в качестве входных данных, два свойства с одинаковым именем Policy в одном объекте / карте в JSON невозможны.

2. Я думаю json-to-xml , что принимает второй аргумент, чтобы гарантировать обнаружение дублированного ключа, который, по-видимому, вам нужно будет использовать json-to-xml(., map { 'duplicates' : 'reject' }) .

Ответ №1:

Вместо копирования XML-карты, протолкните ее через шаблоны и преобразуйте эту карту в элементы, используя @key для имени:

 <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" 
  xmlns:fn="http://www.w3.org/2005/xpath-functions" 
  exclude-result-prefixes="xs math" version="3.0">
    <xsl:output indent="yes" omit-xml-declaration="no" />

    <xsl:template match="data">
        <xsl:apply-templates select="json-to-xml(.)"/>
    </xsl:template>
    
    <xsl:template match="fn:*[@key]">
        <xsl:element name="{@key}">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
        
    <xsl:template match="fn:map">
        <xsl:apply-templates/>
    </xsl:template>
    
</xsl:stylesheet>