当前位置: 移动技术网 > IT编程>开发语言>JavaScript > xml转json的xslt脚本 v2.6

xml转json的xslt脚本 v2.6

2020年07月07日  | 移动技术网IT编程  | 我要评论

在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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网