【问题标题】:convert xml to jsonx using xslt使用 xslt 将 xml 转换为 jsonx
【发布时间】:2012-10-15 08:59:24
【问题描述】:

任何人都可以帮助我得到下面的数组..我必须生成通用的 xsl .. 输入 XML:

<Login>
    <Groups>
        <Group>
            <Name>john</Name>
            <Password/>
        </Group>
        <Group>
            <Name>john</Name>
            <Password/>
        </Group>
    </Groups>
</Login>

输出:

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <json:object name="Login">
        <json:object name="Groups">
            <json:array name="Group">
                <json:object>
                    <json:string name="Name">john</json:string>
                    <json:string name="Password"/>
                </json:object>
                <json:object>
                    <json:string name="Name">john</json:string>
                    <json:string name="Password"/>
                </json:object>
            </json:array>
        </json:object>
    </json:object>
</json:object>

【问题讨论】:

    标签: xslt xslt-1.0 xslt-2.0 jsonx


    【解决方案1】:

    更通用的解决方案。需要 XSLT 2.0

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    
        <xsl:template match="/">
            <xsl:element name="json:object">
                <xsl:apply-templates />    
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="*[*]">
            <xsl:param name="nodeName" select="name()" />
            <xsl:variable name="firstNodeName" select="name(*[1])" />
    
            <xsl:element name="json:object">
                <xsl:if test="$nodeName">
                    <xsl:attribute name="name" select="$nodeName" />
                </xsl:if>
                <xsl:choose>
                    <xsl:when test="(count(*) > 1) and (every $x in */name() satisfies $x=$firstNodeName)">
                        <xsl:element name="json:array">
                            <xsl:attribute name="name" select="$firstNodeName" />
    
                            <xsl:apply-templates >
                                <xsl:with-param name="nodeName" select="''" />
                            </xsl:apply-templates>
                        </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="*[not(*)]">
            <xsl:element name="json:string">
                <xsl:attribute name="name">
                    <xsl:value-of select="name()" />
                </xsl:attribute>
                <xsl:value-of select="text()" />
            </xsl:element>
        </xsl:template> 
    </xsl:stylesheet>
    

    应用于提供的示例 XML,产生以下输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
        <json:object name="Login">
            <json:object name="Groups">
                <json:array name="Group">
                    <json:object>
                        <json:string name="Name">john</json:string>
                        <json:string name="Password"></json:string>
                    </json:object>
                    <json:object>
                        <json:string name="Name">john</json:string>
                        <json:string name="Password"></json:string>
                    </json:object>
                </json:array>
            </json:object>
        </json:object>
    </json:object>
    

    以上方案在本站测试:http://xslttest.appspot.com/

    编辑:

    every $x in */name() satisfies $x=$firstNodeName 是 XPATH 2.0 构造,用于检查 */name() 序列中的所有元素是否等于 $firstNodeName。所以这整个条件实际上意味着检查一个节点是否有多个同名的子节点——这是一个检查我们是否正在处理json:array案例的条件。

    【讨论】:

    • 嗨,Baran,非常感谢您的快速回复...是否可以在不提及元素名称的情况下拥有通用 xsl...
    • @user1731504 查看我的编辑。我试图适应您的示例代码提出的“规则”。 HTH
    • 嗨,Baran,谢谢您的回复。我会试试看
    • 嗨,Baran,我试过这个,但它没有生成对象 ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="w3.org/2001/XMLSchema-instance"> john john
    • @LukaszBaran-- 能否请您提供 v 1.0 中的解决方案?
    【解决方案2】:
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
    <xsl:strip-space elements="*" />
    <!-- Array -->
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
      <json:object name="{name()}">
        <json:array name="{name(*[1])}">
          <xsl:apply-templates />
        </json:array>
      </json:object>
    </xsl:template>
    <!-- Array member -->
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
      <json:object>
        <xsl:apply-templates />
      </json:object>
    </xsl:template>
    <!-- Object -->
    <xsl:template match="*">
      <json:object name="{name()}">
        <xsl:apply-templates />
      </json:object>
    </xsl:template>
    <!-- String -->
    <xsl:template match="*[not(*)]">
      <json:string name="{name()}">
        <xsl:value-of select="." />
      </json:string>
    </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 对代码的一些解释或相关文档的链接以供深入了解和学习通常对作者有所帮助。
    【解决方案3】:

    您可以尝试以下通用 xslt:

    <?xml version="1.0"?>
    
    <xsl:stylesheet xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <xsl:output omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
    
    <xsl:strip-space elements="*"/>
    
    <!-- Array -->
    
    
    
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
    
    
    <json:object name="{name()}">
    
    
    <json:array name="{name(*[1])}">
    
    <xsl:apply-templates/>
    
    </json:array>
    
    </json:object>
    
    </xsl:template>
    
    <!-- Array member -->
    
    
    
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
    
    
    <json:object>
    
    <xsl:apply-templates/>
    
    </json:object>
    
    </xsl:template>
    
    <!-- Object -->
    
    
    
    <xsl:template match="*">
    
    
    <json:object name="{name()}">
    
    <xsl:apply-templates/>
    
    </json:object>
    
    </xsl:template>
    
    <!-- String -->
    
    
    
    <xsl:template match="*[not(*)]">
    
    
    <json:string name="{name()}">
    
    <xsl:value-of select="."/>
    
    </json:string>
    
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      相关资源
      最近更新 更多