xslt 根据其孙节点的属性值选择祖父节点

发布于 2024-09-19 12:27:25 字数 2507 浏览 5 评论 0原文

我试图根据其孙节点的属性值向节点添加不同的标签。

示例输入(1x3 表):

<table>
    <row>
        <cell row="1" column="1" >heading text one</cell>
    </row>

    <row>
        <cell row="2" column="1" >body text one</cell>
    </row>
    <row>
        <cell row="3" column="1" >body text two</cell>
    </row>
</table>

需要这样的输出:

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>

    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>

基本上我只能根据单元格的 @row 元素来确定该行是否是标题行。

这是我尝试过的:

<xsl:template name="matcheverything" match="table">
    <xsl:apply-templates select="row" />
</xsl:template>

<xsl:template name="matchheadings" match="table[*/*/@row=1]">
    <BodyElmt>
        <xsl:apply-templates select="row" />
    </BodyElmt>
</xsl:template>

<xsl:template match="row">
    <xsl:choose>
        <xsl:when test="*/@row=1">
            <HeadingElmt><RowElmt>
                <xsl:apply-templates select="cell"/>
            </RowElmt></HeadingElmt>
        </xsl:when>
        <xsl:otherwise>
            <RowElmt>
                <xsl:apply-templates select="cell"/>
            </RowElmt>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="cell">
    <CellElmt><xsl:apply-templates select="*"/></CellElmt>
</xsl:template>

我认为“matchheadings”模板具有更具体的匹配要求,应该识别标题行,但它实际上匹配表中的每一行。

所以我从这个样式表中的实际输出是每一行都被视为标题行 - 非常糟糕:(

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>

        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </HeadingElmt>
</TableElmt>

I'm trying to add different tags to a node depending on an attribute value of its grandchild node.

Sample Input (a 1x3 table):

<table>
    <row>
        <cell row="1" column="1" >heading text one</cell>
    </row>

    <row>
        <cell row="2" column="1" >body text one</cell>
    </row>
    <row>
        <cell row="3" column="1" >body text two</cell>
    </row>
</table>

Need output like this:

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>

    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>

Basically I can only decide if the row is a heading row based on the @row element of the cell.

Here's what I've tried:

<xsl:template name="matcheverything" match="table">
    <xsl:apply-templates select="row" />
</xsl:template>

<xsl:template name="matchheadings" match="table[*/*/@row=1]">
    <BodyElmt>
        <xsl:apply-templates select="row" />
    </BodyElmt>
</xsl:template>

<xsl:template match="row">
    <xsl:choose>
        <xsl:when test="*/@row=1">
            <HeadingElmt><RowElmt>
                <xsl:apply-templates select="cell"/>
            </RowElmt></HeadingElmt>
        </xsl:when>
        <xsl:otherwise>
            <RowElmt>
                <xsl:apply-templates select="cell"/>
            </RowElmt>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="cell">
    <CellElmt><xsl:apply-templates select="*"/></CellElmt>
</xsl:template>

I was thinking the "matchheadings" template, having a more specific match requirement, should recognize the heading row, however it's actually matching every single row in the table.

So my actual out put from this stylesheet is every row treated as a heading row - very bad :(

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>

        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </HeadingElmt>
</TableElmt>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

允世 2024-09-26 12:27:25

此转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="table">
  <TableElmt>
   <xsl:apply-templates/>
  </TableElmt>
 </xsl:template>

 <xsl:template match="row[cell/@row='1']">
  <HeadingElmt>
   <xsl:apply-templates select="." mode="copy"/>
  </HeadingElmt>
 </xsl:template>

 <xsl:template match="row[cell[not(@row='1')]][1]">
  <BodyElmt>
   <xsl:apply-templates select=".|following-sibling::row" mode="copy"/>
  </BodyElmt>
 </xsl:template>

 <xsl:template match="row" mode="copy">
   <RowElmt>
     <xsl:apply-templates/>
   </RowElmt>
 </xsl:template>

 <xsl:template match="cell">
   <CellElmt>
    <xsl:value-of select="."/>
   </CellElmt>
 </xsl:template>

 <xsl:template match="row"/>
</xsl:stylesheet>

应用于提供的 XML 文档时

<table>
    <row>
        <cell row="1" column="1" >heading text one</cell>
    </row>
    <row>
        <cell row="2" column="1" >body text one</cell>
    </row>
    <row>
        <cell row="3" column="1" >body text two</cell>
    </row>
</table>

产生所需的正确结果

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>
    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="table">
  <TableElmt>
   <xsl:apply-templates/>
  </TableElmt>
 </xsl:template>

 <xsl:template match="row[cell/@row='1']">
  <HeadingElmt>
   <xsl:apply-templates select="." mode="copy"/>
  </HeadingElmt>
 </xsl:template>

 <xsl:template match="row[cell[not(@row='1')]][1]">
  <BodyElmt>
   <xsl:apply-templates select=".|following-sibling::row" mode="copy"/>
  </BodyElmt>
 </xsl:template>

 <xsl:template match="row" mode="copy">
   <RowElmt>
     <xsl:apply-templates/>
   </RowElmt>
 </xsl:template>

 <xsl:template match="cell">
   <CellElmt>
    <xsl:value-of select="."/>
   </CellElmt>
 </xsl:template>

 <xsl:template match="row"/>
</xsl:stylesheet>

when applied on the provided XML document:

<table>
    <row>
        <cell row="1" column="1" >heading text one</cell>
    </row>
    <row>
        <cell row="2" column="1" >body text one</cell>
    </row>
    <row>
        <cell row="3" column="1" >body text two</cell>
    </row>
</table>

produces the wanted, correct result:

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>
    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>
恍梦境° 2024-09-26 12:27:25

编辑:看来我错过了这个

基本上我只能决定该行是否
是基于@row的标题行
细胞的元素。

该样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="table">
        <TableElmt>
            <HeadingElmt>
                <xsl:apply-templates select="row[cell/@row=1]"/>
            </HeadingElmt>
            <BodyElmt>
                <xsl:apply-templates select="row[cell/@row!=1]"/>
            </BodyElmt>
        </TableElmt>
    </xsl:template>
    <xsl:template match="row">
        <RowElmt>
            <xsl:apply-templates/>
        </RowElmt>
    </xsl:template>
    <xsl:template match="cell">
        <CellElmt>
            <xsl:apply-templates/>
        </CellElmt>
    </xsl:template>
</xsl:stylesheet>

输出:

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>
    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>

Edit: It looks like I missed this

Basically I can only decide if the row
is a heading row based on the @row
element of the cell.

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="table">
        <TableElmt>
            <HeadingElmt>
                <xsl:apply-templates select="row[cell/@row=1]"/>
            </HeadingElmt>
            <BodyElmt>
                <xsl:apply-templates select="row[cell/@row!=1]"/>
            </BodyElmt>
        </TableElmt>
    </xsl:template>
    <xsl:template match="row">
        <RowElmt>
            <xsl:apply-templates/>
        </RowElmt>
    </xsl:template>
    <xsl:template match="cell">
        <CellElmt>
            <xsl:apply-templates/>
        </CellElmt>
    </xsl:template>
</xsl:stylesheet>

Output:

<TableElmt>
    <HeadingElmt>
        <RowElmt>
            <CellElmt>heading text one</CellElmt>
        </RowElmt>
    </HeadingElmt>
    <BodyElmt>
        <RowElmt>
            <CellElmt>body text one</CellElmt>
        </RowElmt>
        <RowElmt>
            <CellElmt>body text two</CellElmt>
        </RowElmt>
    </BodyElmt>
</TableElmt>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文