Жидкий шаблон для получения узла XML и дочерних узлов xml, как в формате json

Я пытаюсь шаблон Liquid преобразовать XML в Json с некоторым преобразованием. У меня есть образец XML, как показано ниже

Образец XML:

<Employees>
 <Employee>
  <name>abc</name>
  <summary>
   <Age>15</Age>
   <tag1>dd</tag1>
   <tag2>dd</tag2>
   <tag2>dd</tag2>
  </summary>
 </Employee>
</Employees>

Шаблон My Liquid

{
"Root": 
    [
     {% for employees in content.Employees %}
    {
        "Name": "{{employees.name}}",
        "Summary": "summary is {{employees.summary}}",
  "Age": "{{employees.summary.Age}}"
    },
    {% endfor %}
    ]
}

Я получил Вывод, как показано ниже

{
"Root": [
 {
  "Name": "abc",
  "Summary": "summary is ",
  "Age": "15"
 }
 ]
}

Для узла Summary json я хочу отобразить полный сводный узел xml и дочерние узлы как есть (формат xml), но теперь я получаю пустой. Я попытался найти это в жидком шаблоне, и у меня не было возможности добиться этого. Если это невозможно, то какие альтернативы можно использовать в приложениях логики Azure.

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

 {
"Root": [
 {
  "Name": "abc",
  "Summary": "summary is <summary><Age>15</Age><tag1>dd</tag1><tag2>dd</tag2><tag2>dd</tag2></summary>",
  "Age": "15"
 }
 ]
}

person techresearch    schedule 05.02.2021    source источник


Ответы (1)


XSLT 3 может преобразовать ваш XML в JSON с помощью

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">
    
  <xsl:strip-space elements="*"/>

  <xsl:output method="json" indent="yes"/>

  <xsl:template match="/Employees">
    <xsl:sequence
      select="map { 'Root' : 
                  array { 
                      Employee ! map { 'Name' : data(name), 'Summary' : 'Summary is ' || serialize(summary), 'Age' : number(summary/Age) }
                  }
              }"/>
  </xsl:template>
  
</xsl:stylesheet>

Результат:

 {
  "Root": [
     {
      "Summary":"Summary is <summary><Age>15<\/Age><tag1>dd<\/tag1><tag2>dd<\/tag2><tag2>dd<\/tag2><\/summary>",
      "Name":"abc",
      "Age":15
     }
   ]
 }

https://xsltfiddle.liberty-development.net/6q1SDkM/1

Я думаю, что вы уже можете использовать XSLT 3 на основе Saxon 9 .NET в приложениях Azure.

person Martin Honnen    schedule 05.02.2021
comment
Это работает, как ожидалось. Но когда я запускаю приложение логики, пространство имен добавляется к сводке, например ‹summary xmlns: xsi = \ http: \ / \ / www.w3.org \ / 2001 \ / XMLSchema-instance \ xmlns: xsd = \ http: \ / \ / www.w3.org \ / 2001 \ / XMLSchema \ ›. Еще одна вещь, которую я хотел, - это проверить условие типа Employee.tag2 = somevalue, а затем выполнить только логику карты - person techresearch; 05.02.2021
comment
@techresearch, я не могу сказать, почему вы получаете эти пространства имен, если они не объявлены где-то в дереве, например. на элементе Employees. Что касается второй проблемы, связанной с проверкой условия, внутри XSLT вы, очевидно, можете легко использовать Employee[tag2 = 'somevalue'] ! map { .. } вместо Employee ! map { .. }, показанного выше, для заполнения массива JSON только из Employee элементов, соответствующих этому условию. - person Martin Honnen; 05.02.2021
comment
Отлично!! Это xml-кондиционирование работает должным образом. Как вы упомянули в моем исходном XML, у меня есть пространство имен в дереве, поэтому оно появляется. Если я удалю это пространство имен, оно не появится в итоге. Могу ли я как-нибудь справиться с этим удалением пространства имен из сводки вывода в самом XSLT. - person techresearch; 05.02.2021
comment
@techresearch, вы можете протолкнуть сводный элемент в режиме, в котором используется copy-namespaces="no". Если вам нужна помощь по этому поводу, лучше поднимите это как отдельный вопрос. - person Martin Honnen; 05.02.2021
comment
Я создал новый вопрос для этого stackoverflow.com/questions/66098112/ - person techresearch; 08.02.2021