我有一个逐句定时的语音XML表示。
<speech>
<sentence start="23.56" end="24.67">blah blah... blah</sentence>
...
</speech>
尽管句子中有更多的结构,但编写XSLT来选择所需的信息以获得像这样的简单版本是很简单的
23.56 24.67 blah blah... blah
...
当句子中有时间戳元素时,困难就出现了
<sentence start="23.56" end="24.67">blah blah... <ts t="24.01"/> blah blah... </sentence>
所需的输出是句子拆分:
23.56 24.01 blah blah... blah
24.01 24.67 blah blah... blah
在我对XSLT的简短理解中;句子";包括一个或多个";ts";是一个子树,我需要用两个或多个";句子";根据";ts";元素,因此在此之后,将在";琐碎的";
如有任何帮助,我们将不胜感激。
编辑以澄清
从最简单的输入
<speech>
<sentence start="23.56" end="24.67">Sed ut perspiciatis, <ts t="24.01"/> unde omnis iste natus error</sentence>
</speech>
我正在尝试获得纯文本输出
23.56 24.01 Sed ut perspiciatis,
24.01 24.67 unde omnis iste natus error
我对转换树的评论是将问题视为的第一步
<speech>
<sentence start="23.56" end="24.01">Sed ut perspiciatis,</sentence>
<sentence start="24.01" end="24.67">unde omnis iste natus error</sentence>
</speech>
然后是对所需输出的琐碎转换。
您可以使用在XSLT2或3中分割片段
<xsl:template match="sentence">
<xsl:for-each-group select="node()" group-ending-with="ts">
<sentence>
<xsl:apply-templates select="current-group()[not(self::ts)]"/>
</sentence>
</xsl:for-each-group>
</xsl:template>
上面缺少开始和结束属性的计算,我还没有完全理解这个例子,也许是
<xsl:template match="sentence">
<xsl:for-each-group select="node()" group-ending-with="ts">
<sentence
start="{let $pos := position()
return
if ($pos eq 1)
then ../@start
else ../ts[$pos - 1]/@t}"
end="{if (current-group()[last()] instance of element(ts)) then current-group()[last()]/@t else ../@end}">
<xsl:apply-templates select="current-group()[not(self::ts)]"/>
</sentence>
</xsl:for-each-group>
</xsl:template>
做对了。