欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

xml转json的xslt脚本 v2.6

程序员文章站 2022-04-19 14:05:18
在v2.5版本基础上增加了对于嵌套数组输出的支持,但同时也增加了20%左右的执行耗时;两个版本均可以分别作为最终版本使用,因为在数据交换的应用需求场景,采取嵌套数组的情形几乎不会存在。当元素同时符合以下各项条件,子元素作为嵌套数组输出:1、正被输出为数组中的一项;2、不存在待输出属性;3、不存在文本节点;4、所有子元素与本元素同名;5、子元素应当按数组方式输出。脚本如下:

在v2.5版本基础上增加了对于嵌套数组输出的支持,但同时也增加了20%左右的执行耗时;两个版本均可以分别作为最终版本使用,因为在数据交换的应用需求场景,采取嵌套数组的情形几乎不会存在。

当元素同时符合以下各项条件,子元素作为嵌套数组输出:
1、正被输出为数组中的一项;
2、不存在待输出属性;
3、不存在文本节点;
4、所有子元素与本元素同名;
5、子元素应当按数组方式输出。

脚本如下:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="text" encoding="utf-8"/>
	
	<xsl:template match="*">
		<xsl:param name="indents"/><xsl:param name="inArray"/>
		<xsl:choose>
			<xsl:when test="$inArray = 1 and not(@*[not(starts-with(name(), &apos;json..&apos;)) and not(starts-with(name(), &apos;json:&apos;))]) and not(text()) and not(*[name()!=name(..)][1]) and (*[1]/@json..Array or @*[name()=&apos;json:Array&apos;] or *[2])">
				<xsl:text>[</xsl:text>
				<xsl:for-each select="*">
					<xsl:if test="position() &gt; 1">,</xsl:if>
					<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>
					<xsl:apply-templates select="."><xsl:with-param name="indents" select="concat($indents, &apos;&#x09;&apos;)"/><xsl:with-param name="inArray" select="1"/></xsl:apply-templates>
				</xsl:for-each>
				<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents)"/><xsl:text>]</xsl:text>
			</xsl:when>
			<xsl:when test="* or @*[not(starts-with(name(), &apos;json..&apos;)) and not(starts-with(name(), &apos;json:&apos;))]">
				<xsl:text>{</xsl:text>
				<xsl:for-each select="@*[not(starts-with(name(), &apos;json..&apos;)) and not(starts-with(name(), &apos;json:&apos;))]">
					<xsl:if test="position() &gt; 1">,</xsl:if>
					<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>"@<xsl:value-of select="name()"/><xsl:text>":"</xsl:text>
					<xsl:call-template name="output-string"><xsl:with-param name="string" select="."/></xsl:call-template>
					<xsl:text>"</xsl:text>
					<xsl:if test="position() = last()"><xsl:if test="../node()">,</xsl:if></xsl:if>
				</xsl:for-each>
				<xsl:for-each select="text()">
					<xsl:if test="position() = 1">
						<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>
						<xsl:text>"#text":</xsl:text>
						<xsl:if test="last() &gt; 1">[</xsl:if>
					</xsl:if>
					<xsl:if test="position() > 1">,</xsl:if>
					<xsl:if test="last() &gt; 1">						
						<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&#x09;&apos;)"/>
					</xsl:if>
					<xsl:text>"</xsl:text>
					<xsl:call-template name="output-string"><xsl:with-param name="string" select="."/></xsl:call-template>
					<xsl:text>"</xsl:text>					
					<xsl:if test="position() = last()">
						<xsl:if test="last() &gt; 1"><xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>]</xsl:if>
						<xsl:if test="../*">,</xsl:if>
					</xsl:if>
				</xsl:for-each>
				<xsl:for-each select="*">
					<xsl:variable name="eleName" select="name()"/>
					<xsl:choose>
						<xsl:when test="preceding-sibling::*[name()=$eleName]" />
						<xsl:otherwise>
							<xsl:if test="position() &gt; 1" >,</xsl:if>
							<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>"<xsl:value-of select="name()"/><xsl:text>":</xsl:text>
							<xsl:choose>
								<xsl:when test="@json..Array or @*[name()=&apos;json:Array&apos;] or following-sibling::*[name()=$eleName]">
									<xsl:text>[</xsl:text>
									<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&#x09;&apos;)"/>
									<xsl:apply-templates select="."><xsl:with-param name="indents" select="concat($indents, &apos;&#x09;&#x09;&apos;)"/><xsl:with-param name="inArray" select="1"/></xsl:apply-templates>
									<xsl:for-each select="following-sibling::*[name()=$eleName]">
										<xsl:text>,</xsl:text>
										<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&#x09;&apos;)"/>
										<xsl:apply-templates select="."><xsl:with-param name="indents" select="concat($indents, &apos;&#x09;&#x09;&apos;)"/><xsl:with-param name="inArray" select="1"/></xsl:apply-templates>
									</xsl:for-each>
									<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents, &apos;&#x09;&apos;)"/>
									<xsl:text>]</xsl:text>
								</xsl:when>
								<xsl:otherwise>
									<xsl:apply-templates select="."><xsl:with-param name="indents" select="concat($indents, &apos;&#x09;&apos;)"/></xsl:apply-templates>
								</xsl:otherwise>
							</xsl:choose>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:for-each>
				<xsl:value-of select="concat(&apos;&#x0D;&#x0A;&apos;, $indents)"/><xsl:text>}</xsl:text>
			</xsl:when>
			<xsl:otherwise>
				<xsl:choose>
					<xsl:when test="@json..Type or @*[name()=&apos;json:Type&apos;]">
						<xsl:choose>
							<xsl:when test="text()"><xsl:value-of select="text()"/></xsl:when>
							<xsl:otherwise>null</xsl:otherwise>
						</xsl:choose>
					</xsl:when>
					<xsl:otherwise>
						<xsl:choose>
							<xsl:when test="text()">
								<xsl:text>"</xsl:text>
								<xsl:call-template name="output-string"><xsl:with-param name="string" select="text()"/></xsl:call-template>
								<xsl:text>"</xsl:text>
							</xsl:when>
							<xsl:otherwise>""</xsl:otherwise>
						</xsl:choose>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="output-string">
		<xsl:param name="string" />
		<xsl:if test="$string != &apos;&apos;">
			<xsl:choose>
				<xsl:when test="contains($string, &apos;&#x09;&apos;) or contains($string, &apos;&#x0A;&apos;) or contains($string, &apos;&#x0D;&apos;) or contains($string, &apos;&quot;&apos;) or contains($string, &apos;\&apos;)">
					<xsl:choose>
						<xsl:when test="starts-with($string, &apos;&#x09;&apos;)">\t</xsl:when>
						<xsl:when test="starts-with($string, &apos;&#x0A;&apos;)">\n</xsl:when>
						<xsl:when test="starts-with($string, &apos;&#x0D;&apos;)">\r</xsl:when>
						<xsl:when test="starts-with($string, &apos;&quot;&apos;)">\"</xsl:when>
						<xsl:when test="starts-with($string, &apos;\&apos;)">\\</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="substring($string, 1, 1)"/>
						</xsl:otherwise>
					</xsl:choose>
					<xsl:call-template name="output-string"><xsl:with-param name="string" select="substring($string, 2)"/></xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$string"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:if>
	</xsl:template>

</xsl:stylesheet>

本文地址:https://blog.csdn.net/weixin_42297366/article/details/107153202