У меня есть ввод 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>"</xsl:text><xsl:value-of select = "."/><xsl:text>"</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"
}
Как правильно это сделать?
@ michael.hor257k Я обновил код xsl, который пробовал. Но это все еще не дает правильного результата. Каков правильный путь для этого? Я опубликовал вывод и xsl, который я пробовал.
Проблема в том, что ваше преобразование нуждается в этом вводе <STATS><Apple>4</Apple><Orange>1876</Orange><Kiwi>9</Kiwi></STATS>, чтобы получить {"STATS" :{"Apple" :"4","Orange" :"1876","Kiwi" :"9"}}
@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>
@KarthikGullapalli Это была хорошая попытка. См. другие ответы, чтобы понять, как работать с разделителями.
Спасибо @Alejandro. Я просмотрел здесь другие сообщения и понял, как этого добиться. Похоже, что преобразование XML в JSON с использованием XSL для различных типов преобразований требует разной логики.





Учитывая ввод хорошо сформированный (!), такой как:
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 из вашего кода. И это помогло мне в решении проблемы, над которой я работаю.
Одной из возможностей получения этого вывода 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: {
</xsl:text>
<xsl:apply-templates select = "STATS" />
<xsl:text>
}</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>,
</xsl:text></xsl:if>
</xsl:template>
</xsl:stylesheet>
Его вывод:
STATS: {
"Apple": 4,
"Orange": 1876,
"Kiwi": 9
}
В вашем вводе
STATSэто элементы, а не атрибуты. И вам не хватает корневого элемента. Кроме того, я не вижу никакой связи между вашим XSLT и XML.