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

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

Я хотел бы создать только один элемент атрибута "stats" для каждого из существующих атрибутов и поместить его в 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
}

UPDATE: Я пробовал это 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"
            }

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

Ответы [ 2 ]

1 голос
/ 19 марта 2019

Одной из возможностей достижения этого вывода 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
}
1 голос
/ 19 марта 2019

С учетом правильно сформированного (!) ввода, такого как:

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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...