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

ичок в XSLT, у меня есть простой JSON, который я хочу преобразовать в XML с помощью XSLT 3.0. Я пробовал функции parsejson и jsontoxml в соответствии с рекомендациями w3c, но вывод получился не в нужном формате. Я использую процессор Saxonica для этой цели. Можно ли написать один xslt, который можно использовать в любом заданном json определенной структуры независимо от имен ключей. В противном случае, как я могу подойти, чтобы преобразовать JSON в желаемый XML с помощью функций XSLT

Я попробовал пример в ответе: [Преобразование JSON в XML в XSLT 3.0, но у меня не работает

Ввод JSON

<data>{

      "Assets": [
  { "Asset": {        
        "Open": "25.15",
        "High": "25.15",
        "Low": "25.11",
        "Close": "25.87"
      }},
      { "Asset": {        
        "Open": "25.15",
        "High": "25.15",
        "Low": "25.11",
        "Close": "25.87"
      }}]

}
</data>

Ожидаемый результат

<data>
   <Assets>
      <Asset>
         <Close>25.87</Close>
         <High>25.15</High>
         <Low>25.11</Low>
         <Open>25.15</Open>
      </Asset>
      <Asset>
         <Close>25.87</Close>
         <High>25.15</High>
         <Low>25.11</Low>
         <Open>25.15</Open>
      </Asset>
   </Assets>
</data>

Фактический вывод, который я получил, используя мой xslt

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <array key="Assets">
      <map>
         <map key="Asset">
            <string key="Open">25.15</string>
            <string key="High">25.15</string>
            <string key="Low">25.11</string>
            <string key="Close">25.87</string>
         </map>
      </map>
      <map>
         <map key="Asset">
            <string key="Open">25.15</string>
            <string key="High">25.15</string>
            <string key="Low">25.11</string>
            <string key="Close">25.87</string>
         </map>
      </map>
   </array>
</map>

Моя функция XSLT

<?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>

Ниже приведен пример кода, который я использую с saxon для преобразования

        var xslt = new FileInfo("myxslt.xslt");
        var input = new FileInfo("inputxml.xml");

        // Compile stylesheet
        var processor = new Processor(true);
        var compiler = processor.NewXsltCompiler();
        var executable = compiler.Compile(new Uri(xslt.FullName));
        Serializer serializer = processor.NewSerializer();
        serializer.SetOutputFile(txtOutput.Text);

        // Do transformation to a destination
        var destination = new XdmDestination();
        using (var inputStream = input.OpenRead())
        {
            var transformer = executable.Load();
            transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
            transformer.Run(serializer);
        }
 Martin Honnen01 дек. 2017 г., 10:52
Ну, проблема в том, что{"key 1" : 1} как JSON с желаемым форматом приведет к имени элементаkey 1 это не разрешенное имя. Вот почему форматjson-to-xml функция return помещает имя свойства JSON в атрибут. Таким образом, хотя написание преобразования из XML, которое вы в настоящее время получаете в нужный вам, тривиально для представленного вами ввода, неясно, какой результат вы хотите получить в целом.
 user181770101 дек. 2017 г., 12:12
@MartinHonnen: Спасибо за ответ и примечание о месте в ключе. Я думаю, мне придется справиться с этим перед передачей json процессору xslt. Я прав?

Ответы на вопрос(1)

Решение Вопроса

Это тривиально, чтобы решить, что для вашего данного входа с

<xsl:template match="data">
    <xsl:copy>
        <xsl:apply-templates select="json-to-xml(.)/*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[@key]" xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
    <xsl:element name="{@key}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

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

 Michael Kay01 дек. 2017 г., 12:33
Вам могут понадобиться дополнительные правила, например, для обработки вложенных массивов: главное, что не существует единого универсального способа представления таких структур в XML, поэтому вы должны сделать свой собственный выбор.
 user181770101 дек. 2017 г., 12:01
Большое спасибо. Это именно то, что я хотел. Я хотел преобразовать JSON в xml и применить другие функции xslt для манипулирования данными, чтобы создать плоский xml.

Ваш ответ на вопрос