我对XSLT很陌生,这个示例看起来是一种很好的学习方式,但就我的一生而言,它无法发挥作用。我试图并行标记2个不同的字符串,并将它们组合成一个JSON数组。所以我想标记measTypes[0]并匹配到measResults[0],然后标记measTTypes[1]并匹配到measResults[1],依此类推
示例XML
<?xml version="1.0" encoding="UTF-8"?>
<measInfo measInfoId="1542455297">
<measTypes>1542455297 1542455298 1542455299 1542455300 1542455301 1542455302 1542455303 1542455304 1542455305 1542455306 1542455307 1542460296 1542460297 </measTypes>
<measValue measObjLdn="LTHAB0113422/ETHPORT:Cabinet No.=0, Subrack No.=1, Slot No.=7, Port No.=0, Subboard Type=BASE_BOARD">
<measResults>116967973 585560 496041572 682500 0 12583680 72080 520454 46670568 73432 2205837 1000000 1000000 </measResults>
</measValue>
<measValue measObjLdn="LTHAB0113422/ETHPORT:Cabinet No.=0, Subrack No.=1, Slot No.=7, Port No.=1, Subboard Type=BASE_BOARD">
<measResults>0 0 0 0 0 0 0 0 0 0 0 0 0 </measResults>
</measValue>
</measInfo>
到目前为止我已经有了XSLT2.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform” xmlns:xs="http://www.w3.org/2001/XMLSchema” exclude-result-prefixes=“xs" version="2.0">
<xsl:output method="text" encoding="UTF-8" media-type="text/plain"/>
<xsl:strip-space elements="*"/>
<!--
<xsl:template match="/measInfo/measValue/measResults" name="measRes">
<xsl:for-each select=".">
{'measResult':{<xsl:value-of select="tokenize(normalize-space(.),'s+')"/>}
</xsl:for-each>
</xsl:template>
-->
<xsl:template match="/" name="measObj">
[
<xsl:for-each select="measInfo/measValue">
'measObjLdn':'<xsl:value-of select="@measObjLdn"/>'
<xsl:call-template name="types"/>
</xsl:for-each>
]
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/measInfo" name="types" >
'Metrics':[
<xsl:for-each select="tokenize(normalize-space(measTypes),'s+')">
{'measType':'<xsl:value-of select="."/>'},<!-- <xsl:call-template name="measRes"/> -->
</xsl:for-each>
]
</xsl:template>
</xsl:stylesheet>
我希望的JSON结果
[
'measObjLdn':"LTHAB0113422/ETHPORT:Cabinet No.=0, Subrack No.=1, Slot No.=7, Port No.=0, Subboard Type=BASE_BOARD",
'Metrics':[
{'measType':'1542455297','measResult':116967973},
{'measType':'1542455298','measResult':585560},
{'measType':'1542455299','measResult':496041572},
{'measType':'1542455300','measResult':682500},
{'measType':'1542455301','measResult':0},
{'measType':'1542455302','measResult':12583680},
{'measType':'1542455303','measResult':72080},
{'measType':'1542455304','measResult':520454},
{'measType':'1542455305','measResult':46670568},
{'measType':'1542455306','measResult':73432},
{'measType':'1542455307','measResult':2205837},
{'measType':'1542460296','measResult':1000000},
{'measType':'1542460297','measResult':1000000}
]
'measObjLdn':"LTHAB0113422/ETHPORT:Cabinet No.=0, Subrack No.=1, Slot No.=7, Port No.=1, Subboard Type=BASE_BOARD",
'Metrics':[
{'measType':'1542455297','measResult':0},
{'measType':'1542455298','measResult':0},
{'measType':'1542455299','measResult':0},
{'measType':'1542455300','measResult':0},
{'measType':'1542455301','measResult':0},
{'measType':'1542455302','measResult':0},
{'measType':'1542455303','measResult':0},
{'measType':'1542455304','measResult':0},
{'measType':'1542455305','measResult':0},
{'measType':'1542455306','measResult':0},
{'measType':'1542455307','measResult':0},
{'measType':'1542460296','measResult':0},
{'measType':'1542460297','measResult':0}
]
]
XPath3.0(以及XSLT3.0)具有可以组合使用的功能:
<xsl:value-of select="for-each-pair(tokenize(measTypes), tokenize(measInfo/measValue), function($t, $v) {
serialize(map{'measType':$t, 'measValue':$v}, map{'method':'json'})
})" separator=",&#a;"/>
这里有一种成对处理两个序列的方法:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output media-type="text"/>
<xsl:template match="measInfo">
<xsl:variable name="types" select="tokenize(normalize-space(measTypes), 's+')"/>
[
<xsl:apply-templates select="measValue">
<xsl:with-param name="types" select="$types"/>
</xsl:apply-templates>
]
</xsl:template>
<xsl:template match="measValue">
<xsl:param name="types"/>
{ 'measObjLdn' : '<xsl:value-of select="@measObjLdn"/>' },
<xsl:variable name="values" select="tokenize(normalize-space(), 's+')"/>
'Metrics' :
[
<xsl:for-each select="$types">
<xsl:variable name="pos" select="position()"/>
<xsl:if test="$pos > 1">,
</xsl:if>
{ 'measTypes' : '<xsl:value-of select="."/>', 'measResult' : '<xsl:value-of select="$values[$pos]"/>' }
</xsl:for-each>
]
</xsl:template>
</xsl:stylesheet>
输出的格式不好,但您应该能够自己使用xsl:text
来改进它。