XSL转换失败,我不明白为什么

时间:2016-03-23 14:13:49

标签: regex xml xslt xslt-2.0

作为编写XSL的新手,我正在为我当前的项目调试一个问题。 EditX-XML只是失败了转换错误,但没有说出它们的位置。

任何建议表示赞赏

源XML:

<soa:Label xmlns:soa="urn:telestream.net:soa:core" identifier="ac7af7e5-a536-40ae-b7ca-93e62009c86a" name="Duration - Timecode to Frames" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000">
<soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">00:15:52:10@25
<soa:Default>00:00:00:00@29.97</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
<soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">0
<soa:Default>0</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
</soa:Label>

XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soa="urn:telestream.net:soa:core" version="2.0">
<xsl:analyze-string select="/soa:Label/soa:Parameter[1]" regex="^(\d+):(\d+):(\d+):(\d+)@(\d+)$">
<xsl:matching-substring><xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
<xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
<xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
<xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
<xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
<xsl:variable name="total-frames" select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
</xsl:matching-substring>
</xsl:analyze-string>
<xsl:template match="/">
<soa:Label identifier="5f01d03f-f867-4a57-92e0-19d239a3582d" name="Duration - Timecode to Frames pt2" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000" xmlns:soa="urn:telestream.net:soa:core">
<soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
<xsl:value-of select="/soa:Label/soa:Parameter[1]"/>
<soa:Default>00:00:00:00@29.97</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
<soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1"><xsl:value-of select="$total-frames"/><soa:Default>0</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
</soa:Label>
</xsl:template>
</xsl:stylesheet>

由于

1 个答案:

答案 0 :(得分:0)

如果你要在http://xsltransform.net/测试你的XSLT,你会看到你的XSLT有两个错误

  1. 元素xsl:analyze-string不允许为子女 xsl:stylesheet
  2. 您已定义了一个total-frames变量 这个xsl:analyze-string但这意味着它只在范围内 xsl:matching-substring块,所以不能引用它 其中。
  3. 有关具体详情,请参阅http://xsltransform.net/pPzifqj

    您需要做的是移动xsl:analyze-string,同时在xsl:variable周围包含total-frames声明,以便稍后可以在模板中使用该变量。< / p>

    试试这个XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:soa="urn:telestream.net:soa:core"
                    version="2.0">
        <xsl:output method="xml" indent="yes" />
    
       <xsl:template match="/">
          <soa:Label identifier="5f01d03f-f867-4a57-92e0-19d239a3582d" name="Duration - Timecode to Frames pt2" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000">
             <soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
                <xsl:value-of select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"/>
                <soa:Default>00:00:00:00@29.97</soa:Default>
                <soa:IsRequired>false</soa:IsRequired>
             </soa:Parameter>
    
            <xsl:variable name="total-frames">
                <xsl:analyze-string select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"
                                   regex="^(\d+):(\d+):(\d+):(\d+)@(\d+)$">
                  <xsl:matching-substring>
                     <xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
                     <xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
                     <xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
                     <xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
                     <xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
    
                     <xsl:value-of select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
                  </xsl:matching-substring>
               </xsl:analyze-string>
           </xsl:variable> 
    
             <soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
                <xsl:value-of select="$total-frames"/>
                <soa:Default>0</soa:Default>
                <soa:IsRequired>false</soa:IsRequired>
             </soa:Parameter>
          </soa:Label>
       </xsl:template>
    </xsl:stylesheet>
    

    另请注意您选择soa:Parameter[1]的位置,这也包括文本中的所有换行符以及空白节点,因此您的正则表达式不会匹配。

    话虽如此,看起来你正在尝试做的是根据第一个参数将文本值附加到第二个参数。在这种情况下,您可以从使用XSLT标识模板中受益。

    尝试这个XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:soa="urn:telestream.net:soa:core"
                    version="2.0">
        <xsl:output method="xml" indent="yes" />
    
        <xsl:template match="soa:Parameter[2]">
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:analyze-string select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"
                                   regex="^(\d+):(\d+):(\d+):(\d+)@(\d+)$">
                  <xsl:matching-substring>
                     <xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
                     <xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
                     <xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
                     <xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
                     <xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
    
                     <xsl:value-of select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
                  </xsl:matching-substring>
               </xsl:analyze-string>
                <xsl:apply-templates select="*"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>