【问题标题】:how to apply parallel template definitions in XSLT 2.0如何在 XSLT 2.0 中应用并行模板定义
【发布时间】:2016-12-02 00:08:32
【问题描述】:

我是 XSLT 的新手,这个示例看起来是一种很好的学习方式,但我一生都无法让它发挥作用。我正在尝试并行标记 2 个不同的字符串并将它们组合成一个 JSON 数组。所以我想标记 measTypes[0] 并匹配到 measResults[0],然后是 measTypes[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>

我目前拥有的 XSLT 2.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}
            ]
        ]

【问题讨论】:

  • 'measObjLdn':{LTHAB0113422/ETHPORT:Cabinet No.=0 在我看来不像 JSON。
  • 对不起,太多的剪切和粘贴所有的代码sn-ps。现在应该是正确的
  • 您需要编写一个模板或函数,以两个序列作为参数,然后为每个序列中的第一项对构建 JSON 对象字面量,并在尾部分别调用模板函数序列。 XPath 3.0 有for-each-pair 可以做到这一点,但当然您可以在自己的函数中实现它。 w3.org/TR/xpath-functions-31/#func-for-each-pair

标签: json xml-parsing xslt-2.0


【解决方案1】:

XPath 3.0(以及因此的 XSLT 3.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;"/>

【讨论】:

    【解决方案2】:

    这是成对处理两个序列的一种方法:

    <?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 改进它。

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多