作为编写XSL的新手,我在为当前项目调试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>
感谢
如果您要在http://xsltransform.net/您将看到XSLT 有两个错误
- 元素
xsl:analyze-string
不允许是
的子级xsl:stylesheet
- 您已在
中定义了total-frames
变量这个xsl:analyze-string
,但这意味着它只在xsl:matching-substring
块,因此不能引用它其中
请参阅http://xsltransform.net/pPzifqj具体细节
您需要做的是移动xsl:analyze-string
,但也要将total-frames
的xsl:variable
声明包裹在它周围,以便稍后可以在模板中使用该变量。
尝试此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>