XSLT: как разделить строки для нескольких полей одновременно

Я видел несколько сообщений об использовании tokenize() для разделения строк, но все они связаны с одним полем. У меня немного другая ситуация и я не знаю, как к ней подойти.

Мой XML может выглядеть примерно так:

<somefield>
    <code>A,B,C</code>
    <description>Description of A; Description of B; Description of C</description>
</somefield>

Я хочу преобразовать это во что-то вроде этого:

{
  "somefield": [
    {
      "code": "A",
      "description": "Description of A"
    },
    {
      "code": "B",
      "description": "Description of B"
    },
    {
      "code": "C",
      "description": "Description of C"
    }
  ]
}

Я не совсем понимаю, как разделить оба поля одновременно. Есть идеи?

Пожалуйста, выберите XSLT 1.0 или 2.0, но не обе версии.

michael.hor257k 12.06.2024 18:43

Это недействительный JSON, не так ли?

michael.hor257k 12.06.2024 19:05

Я прошу прощения. Я выбрал несколько версий XSLT, поскольку меня интересовали решения в любой из версий.

DR - Idemia 13.06.2024 15:57

Нет, это недействительный JSON. Это игрушечный пример, и я забыл удалить лишний комментарий. Я исправлю это, если ТАК позволит мне.

DR - Idemia 13.06.2024 15:58

Его все равно нужно заключить в фигурные скобки.

michael.hor257k 13.06.2024 16:00

Решение XSLT 1.0 должно было бы радикально отличаться — если только ваш процессор не поддерживает токенизацию в качестве функции расширения. См. пример здесь: stackoverflow.com/a/62276436/3016153

michael.hor257k 13.06.2024 16:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В XSLT 2.0 вы могли бы сделать что-то вроде

<xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "xml" indent = "yes"/>

<xsl:template match = "/somefield">
    <array key = "somefield">
        <xsl:variable name = "descr" select = "tokenize(description, ';')"/>
        <xsl:for-each select = "tokenize(code, ',')">
            <xsl:variable name = "i" select = "position()"/>
            <map>
                <string key = "code">
                    <xsl:value-of select = "."/>
                </string>
                <string key = "description">
                    <xsl:value-of select = "$descr[$i]"/>
                </string>
            </map>  
        </xsl:for-each>
    </array>    
</xsl:template>

</xsl:stylesheet>

получить:

<?xml version = "1.0" encoding = "UTF-8"?>
<array key = "somefield">
   <map>
      <string key = "code">A</string>
      <string key = "description">Description of A</string>
   </map>
   <map>
      <string key = "code">B</string>
      <string key = "description"> Description of B</string>
   </map>
   <map>
      <string key = "code">C</string>
      <string key = "description"> Description of C</string>
   </map>
</array>

(Извините, у меня нет времени настроить это для вывода JSON.)

Я смог настроить это так, чтобы делать то, что мне нужно. Большое спасибо.

DR - Idemia 13.06.2024 18:50

В 3.0 вы могли бы сделать

  array {
    for-each-pair(tokenize(code, ','),
                  tokenize(description, ';'),
                  function($x, $y) { 
                    map{"code": $x, "description": $y}
                  })
  }

Есть ли способ расширить это до 3 или более последовательностей?

y.arazim 13.06.2024 11:43

@y.arazim, да, ты можешь использовать, например. пример сгиба влево

Martin Honnen 13.06.2024 18:31

Это так элегантно.

DR - Idemia 13.06.2024 18:51

Другие вопросы по теме