Создайте один атрибут «статистика» в JSON из XML, содержащего несколько атрибутов «статистика» в XSLT 1.0

У меня есть ввод XML с элементами, которые имеют ряд атрибутов с именем «статистика».

Я хотел бы создать только один элемент атрибута «статистика» для каждого из существующих атрибутов и поместить его в JSON как один ключ.

Вход:

<STATS>
    <CODE>Apple</CODE><COUNT>4</COUNT>
</STATS>
<STATS>
    <CODE>Orange</CODE><COUNT>1876</COUNT>
</STATS>
<STATS>
    <CODE>Kiwi</CODE><COUNT>9</COUNT>
</STATS>

Выход:

"STATS":{
    "Apple":4,
    "Orange":1876,
    "Kiwi": 9
}

ОБНОВИТЬ: Я пробовал этот XSL

<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text"/>

<xsl:template match = "/">{
    <xsl:apply-templates select = "*"/>}
</xsl:template>

<!-- Object or Element Property-->
<xsl:template match = "*">
    "<xsl:value-of select = "name()"/>" :<xsl:call-template name = "Properties">
        <xsl:with-param name = "parent" select = "'Yes'"> </xsl:with-param>
    </xsl:call-template>
</xsl:template>

<!-- Array Element -->
<xsl:template match = "*" mode = "ArrayElement">
    <xsl:call-template name = "Properties"/>
</xsl:template>

<!-- Object Properties -->
<xsl:template name = "Properties">
    <xsl:param name = "parent"></xsl:param>
    <xsl:variable name = "childName" select = "name(*[1])"/>
    <xsl:choose>            
        <xsl:when test = "not(*|@*)"><xsl:choose><xsl:when test = "$parent='Yes'"> <xsl:text>&quot;</xsl:text><xsl:value-of select = "."/><xsl:text>&quot;</xsl:text></xsl:when>
                <xsl:otherwise>"<xsl:value-of select = "name()"/>":"<xsl:value-of  select = "."/>"</xsl:otherwise>
            </xsl:choose>           
        </xsl:when>                
        <xsl:when test = "count(*[name()=$childName]) > 1">{ "<xsl:value-of  select = "$childName"/>" :[<xsl:apply-templates select = "*" mode = "ArrayElement"/>] }</xsl:when>
        <xsl:otherwise>{
            <xsl:apply-templates select = "@*"/>
            <xsl:apply-templates select = "*"/>
            }</xsl:otherwise>
    </xsl:choose>
    <xsl:if test = "following-sibling::*">,</xsl:if>
</xsl:template>

<!-- Attribute Property -->
<xsl:template match = "@*">"<xsl:value-of select = "name()"/>" : "<xsl:value-of select = "."/>",
</xsl:template>
</xsl:stylesheet>

Но это не работает, похоже. Это дает мне следующий вывод:

    "STATS" :{

    "CODE" :"Apple",
    "COUNT" :"4"
            },
    "STATS" :{

    "CODE" :"Orange",
    "COUNT" :"1876"
            },
    "STATS" :{

    "CODE" :"Kiwi",
    "COUNT" :"9"
            }

Как правильно это сделать?

В вашем вводе STATS это элементы, а не атрибуты. И вам не хватает корневого элемента. Кроме того, я не вижу никакой связи между вашим XSLT и XML.

michael.hor257k 19.03.2019 20:04

@ michael.hor257k Я обновил код xsl, который пробовал. Но это все еще не дает правильного результата. Каков правильный путь для этого? Я опубликовал вывод и xsl, который я пробовал.

Karthik Gullapalli 19.03.2019 20:14

Проблема в том, что ваше преобразование нуждается в этом вводе <STATS><Apple>4</Apple><Orange>1876</Orange><Kiwi>9</Kiwi></‌​STATS>, чтобы получить {"STATS" :{"Apple" :"4","Orange" :"1876","Kiwi" :"9"}}

Alejandro 19.03.2019 20:23

@Alejandro Алехандро, что может быть правильным xslt для данного ввода? Я пробовал что-то вроде этого. <xsl:template match = "/"> <xsl:for-each select = "/STATS"> <xsl:value-of select = "CODE"/> <xsl:value-of select = "COUNT"/> </xsl:for-each> </xsl:template>

Karthik Gullapalli 19.03.2019 20:36

@KarthikGullapalli Это была хорошая попытка. См. другие ответы, чтобы понять, как работать с разделителями.

Alejandro 19.03.2019 21:45

Спасибо @Alejandro. Я просмотрел здесь другие сообщения и понял, как этого добиться. Похоже, что преобразование XML в JSON с использованием XSL для различных типов преобразований требует разной логики.

Karthik Gullapalli 19.03.2019 23:17
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
63
2

Ответы 2

Учитывая ввод хорошо сформированный (!), такой как:

XML

<root>
    <STATS>
        <CODE>Apple</CODE>
        <COUNT>4</COUNT>
    </STATS>
    <STATS>
        <CODE>Orange</CODE>
        <COUNT>1876</COUNT>
    </STATS>
    <STATS>
        <CODE>Kiwi</CODE>
        <COUNT>9</COUNT>
    </STATS>
</root>

следующую таблицу стилей:

XSLT 1.0

<xsl:stylesheet version = "1.0" 
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text" encoding = "utf-8"/>

<xsl:template match = "/root">
    <xsl:text>"STATS":{</xsl:text>
    <xsl:for-each select = "STATS">
        <xsl:text>"</xsl:text>
        <xsl:value-of select = "CODE"/>
        <xsl:text>":</xsl:text>
        <xsl:value-of select = "COUNT"/>
        <xsl:if test = "position()!=last()">,</xsl:if>
    </xsl:for-each>
    <xsl:text>}</xsl:text>
</xsl:template>

</xsl:stylesheet>

вернется:

Результат

"STATS":{"Apple":4,"Orange":1876,"Kiwi":9}

Спасибо за это. Я понимаю, как работает xsl из вашего кода. И это помогло мне в решении проблемы, над которой я работаю.

Karthik Gullapalli 19.03.2019 23:00

Одной из возможностей получения этого вывода JSON является следующий код XSLT-1.0. Предполагается, что ваш входной XML заключен в элемент с именем root, чтобы сделать его хорошо сформированный.

Таким образом, входной XML-файл выглядит следующим образом:

<?xml version = "1.0" encoding = "UTF-8" ?>
<root>
    <STATS>
        <CODE>Apple</CODE><COUNT>4</COUNT>
    </STATS>
    <STATS>
        <CODE>Orange</CODE><COUNT>1876</COUNT>
    </STATS>
    <STATS>
        <CODE>Kiwi</CODE><COUNT>9</COUNT>
    </STATS>
</root>

Файл XSLT-1.0, удовлетворяющий вашим потребностям, выглядит так:

<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text"/>

<xsl:template match = "/root">
    <xsl:text>STATS: {&#xa;</xsl:text>
        <xsl:apply-templates select = "STATS" />
    <xsl:text>&#xa;}</xsl:text>
</xsl:template>

<!-- STATS elements -->
<xsl:template match = "STATS">
    <xsl:text>  "</xsl:text><xsl:value-of select = "CODE"/><xsl:text>": </xsl:text>
    <xsl:value-of select = "COUNT"/>
    <xsl:if test = "position() != last()"><xsl:text>,&#xa;</xsl:text></xsl:if>
</xsl:template>

</xsl:stylesheet>

Его вывод:

STATS: {
  "Apple": 4,
  "Orange": 1876,
  "Kiwi": 9
}

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