首页 文章

XSLT在以后的子节点中使用第一个子节点值

提问于
浏览
0

我有一个HTML文件,使用XSLT转换为XML文件,我只需要抓取第一个子节点的日期值,以便在后面的子节点中使用,因为后面的子节点没有数据值,标签将显得空虚 . 我尝试使用定位来为XSLT做这件事,但无济于事 .

相关的HTML代码是:

<tbody>
  <tr>
    <th rowspan="8" scope="rowgroup">2005DEC</th>  
    <th scope="row">Blemish on Card</th>

  </tr>

  <tr>
    <th scope="row">Damaged</th>

  </tr>

  <tr>
    <th rowspan="8" scope="rowgroup">2006JAN</th>  
    <th scope="row">Lost</th>

  </tr>

  <tr>
    <th scope="row">Stolen</th>

  </tr>
</tbody>

相关的XSLT代码是:

<xsl:for-each select="html/body/div/div/div/table/tbody/tr">
    <Entry>
        <xsl:choose>
            <xsl:when test="th[@scope='rowgroup']">
                <Year>
                    <xsl:value-of select="substring(th[@scope='rowgroup']/., 1, 4)" />
                </Year>
                <Month>
                    <xsl:value-of select="substring(th[@scope='rowgroup']/., 5, 3)" />
                </Month>
            </xsl:when>
            <xsl:otherwise>
                <Year>
                    <xsl:value-of select="substring(tr[1]/th[@scope='rowgroup']/., 1, 4)" />
                </Year>
                <Month>
                    <xsl:value-of select="substring(tr[1]/th[@scope='rowgroup']/., 5, 3)" />
                </Month>
            </xsl:otherwise>
        </xsl:choose>
    </Entry>
</xsl:for-each>

输出的XML代码如下所示,这不是我想要的,因为第二个子节点没有第一个子节点的日期值,只显示为年和月的空值标记:

<Entry>
  <Year>2005</Year>
  <Month>DEC</Month>
  <Reason>Blemish on Card</Reason>
</Entry>
<Entry>
  <Year/>
  <Month/>
  <Reason>Damaged</Reason>
</Entry>
<Entry>
  <Year>2006</Year>
  <Month>JAN</Month>
  <Reason>Lost</Reason>
</Entry>
<Entry>
  <Year/>
  <Month/>
  <Reason>Stolen</Reason>
</Entry>

我需要的是:

<Entry>
  <Year>2005</Year>
  <Month>DEC</Month>
  <Reason>Blemish on Card</Reason>
</Entry>
<Entry>
  <Year>2005</Year>
  <Month>DEC</Month>
  <Reason>Damaged</Reason>
</Entry>
<Entry>
  <Year>2006</Year>
  <Month>JAN</Month>
  <Reason>Lost</Reason>
</Entry>
<Entry>
  <Year>2006</Year>
  <Month>JAN</Month>
  <Reason>Stolen</Reason>
</Entry>

我如何为我的XSLT做到这一点?

1 回答

  • 1

    您必须先向上导航: substring(../tr[1]/th[@scope='rowgroup']/., 1, 4) 如果要从第一行中选择数据 .

    根据您的意见而不是您想要的,如果您想要使用 scope="rowgroup" 属性从第一个前一个兄弟行中选择数据,那么一种方法,继续您的方法是

    <xsl:for-each select="//tbody/tr">
        <Entry>
            <xsl:choose>
                <xsl:when test="th[@scope='rowgroup']">
                    <Year>
                        <xsl:value-of select="substring(th[@scope='rowgroup']/., 1, 4)" />
                    </Year>
                    <Month>
                        <xsl:value-of select="substring(th[@scope='rowgroup']/., 5, 3)" />
                    </Month>
                </xsl:when>
                <xsl:otherwise>
                    <Year>
                        <xsl:value-of select="substring(preceding-sibling::tr[th[@scope='rowgroup']][1]/th[@scope='rowgroup'], 1, 4)" />
                    </Year>
                    <Month>
                        <xsl:value-of select="substring(preceding-sibling::tr[th[@scope='rowgroup']][1]/th[@scope='rowgroup'], 5, 3)" />
                    </Month>
                </xsl:otherwise>
            </xsl:choose>
    
            <xsl:for-each select="th[@scope='row']">
                <Reason>
                    <xsl:value-of select="." />
                </Reason>
            </xsl:for-each>
        </Entry>
    </xsl:for-each>
    

    虽然如果使用XSLT 2.0处理器,我可能更容易使用 for-each-group group-starting-with="tr[th[@scope = 'rowgroup']]" .

相关问题