XSLT值按编号

时间:2017-01-27 13:29:46

标签: xml xslt

您好我正在尝试按段号按顺序提取持续时间码的值。

以下是我输入xml的示例:

<Container>
    <Properties outputFileSegment-1-durationTimeCode="00:00:59;28" outputFileSegment-1-durationTotalFrames="1798" outputFileSegment-1-endTimeCode="00:59:39;29" outputFileSegment-1-endTimeCodeMediaflex="00:59:40;00" outputFileSegment-1-endTotalFrames="107291" outputFileSegment-1-endTotalFramesMediaflex="107292" outputFileSegment-1-segmentType="12" outputFileSegment-1-startTimeCode="00:58:40;00" outputFileSegment-1-startTotalFrames="105494" outputFileSegment-2-durationTimeCode="00:00:17;28" outputFileSegment-2-durationTotalFrames="540" outputFileSegment-2-endTimeCode="00:59:57;29" outputFileSegment-2-endTimeCodeMediaflex="00:59:58;00" outputFileSegment-2-endTotalFrames="107831" outputFileSegment-2-endTotalFramesMediaflex="107832" outputFileSegment-2-segmentType="8" outputFileSegment-2-startTimeCode="00:59:40;00" outputFileSegment-2-startTotalFrames="107292" outputFileSegment-3-durationTimeCode="00:09:06;17" outputFileSegment-3-durationTotalFrames="16379" outputFileSegment-3-endTimeCode="01:09:06;06" outputFileSegment-3-endTimeCodeMediaflex="01:09:06;20" outputFileSegment-3-endTotalFrames="124260" outputFileSegment-3-endTotalFramesMediaflex="124261" outputFileSegment-3-segmentType="63" outputFileSegment-3-startTimeCode="00:59:59;20" outputFileSegment-3-startTotalFrames="107882" />
</Container>

我想要完成的是与此输出类似的最终格式:

<segment>
    <segment_sequence_number>1</segment_sequence_number>
    <segment_length>00:00:59;28</segment_length>
</segment>
<segment>
    <segment_sequence_number>2</segment_sequence_number>
    <segment_length>00:00:17;28</segment_length>
</segment>
<segment>
    <segment_sequence_number>3</segment_sequence_number>
    <segment_length>00:09:06;17</segment_length>
</segment>

我在这一点上陷入困​​境,因为我不知道如何在xslt 1.0中写入以按顺序提取每个持续时间的值,直到最后一个段。有人可以帮助我走上正轨吗?

2 个答案:

答案 0 :(得分:0)

这是你可以看到它的一种方式:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/Container">
    <segments>
        <xsl:for-each select="Properties/@*[substring-after(substring-after(name(), '-'), '-')='durationTimeCode']">
            <segment>
                <segment_sequence_number>
                    <xsl:value-of select="substring-before(substring-after(name(), '-'), '-')" />
                </segment_sequence_number>
                <segment_length>
                    <xsl:value-of select="." />
                </segment_length>
            </segment>
        </xsl:for-each>
    </segments>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

使用XML来构建这样的结构化属性是一种淫秽的方式,通常当你看到如此设计糟糕的XML时,最好的办法是先将它转换为优秀的XML,然后再使用适合您真实逻辑的优秀XML。对于这个输入,我首先将它转换为这样的:

<Container>
    <Properties>
      <segment nr="1">
          <durationTimeCode>00:00:59;28</durationTimeCode>
          <durationTotalFrames>1798</durationTotalFrames>
          <endTimeCode>00:59:39;29</endTimeCode>
          ...
      </segment>
      <segment nr="2">
          ...
      </segment>
   </Properties>
</Container>

可以使用以下模板规则实现此清理。我已经使用过XSLT 2.0,因为它涉及分组和字符串匹配,我真的不能在1.0中解决这个问题,如果你真的需要我会让你自己做Muenchian legwork。

<xsl:template match="Properties">
  <Properties>
    <xsl:for-each-group select="@*" group-by="replace(name(), '[-A-Za-z]', '')">
      <segment nr="{current-grouping-key()}">
        <xsl:for-each select="current-group()">
          <xsl:element name="replace(name(), '^[A-Za-z]-[0-9]-', '')">
            <xsl:value-of select="."/>
          </xsl:element>
        </xsl:for-each>
      </segment>
    </xsl:for-each-group>
  </Properties>
</xsl:template>

我认为这是我生命中第一次对元素的属性进行分组;这是对XML输入的奇怪程度的衡量标准。