【问题标题】:Keep tree stucture in XSL在 XSL 中保持树结构
【发布时间】:2012-07-17 12:56:45
【问题描述】:

我有以下文件:

<Doc>
    <If cond="c">
       <Expr>Expr1</Expr>
    </If>
    <Expr>Expr2</Expr>
</Doc>

应该创建这样的输出:

If c { Expr1 } Expr2

但是,在我的情况下,它会创建:

Expr1 If c { Expr1 } Expr2

我有以下 XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text"/>
    <xsl:template match="/">
       <xsl:element name="Doc">
            <xsl:apply-templates select="*" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="If">
      <xsl:text>if </xsl:text><xsl:value-of select="@cond"/><xsl:text> {</xsl:text>
      <xsl:apply-templates select="Expr"/><xsl:text>}</xsl:text>
    </xsl:template>

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

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

【问题讨论】:

  • 这个想法是 Expr 元素将被转换到正确的位置。嵌套 if 是可能的。我遇到的问题是 Expr-Element 重复了。
  • 简单的解决方案就是从 If 中删除 apply-templates,否则添加 }。

标签: xml xslt xslt-1.0


【解决方案1】:

这种转变

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="If">
     if <xsl:value-of select="@cond"/> <xsl:text/>
     <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="If/Expr">
  <xsl:value-of select="concat(' { ', ., ' }')"/>
 </xsl:template>

 <xsl:template match="Expr">
  <xsl:value-of select="concat(' ', .)"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<Doc>
    <If cond="c">
        <Expr>Expr1</Expr>
    </If>
    <Expr>Expr2</Expr>
</Doc>

产生想要的正确结果

 if c { Expr1 } Expr2

请注意

如果您将转换简化为:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="If">
          <xsl:text>if </xsl:text><xsl:value-of select="@cond"/><xsl:text> {</xsl:text>
          <xsl:apply-templates select="Expr"/><xsl:text>}</xsl:text>
        </xsl:template>

        <xsl:template match="Expr">
            <xsl:value-of select="."/>
        </xsl:template>
</xsl:stylesheet>

然后产生正确的结果

if c {Expr1}
Expr2

【讨论】:

    【解决方案2】:

    总是很难准确理解人们从样式表中要求的行为,但我认为您要问的是'我如何确保只有If 元素下的Expr 元素在括号内转换? '

    尝试将 template match="Expr" 修改为 template match="If/Expr" - 这会告诉转换引擎只有在 Ifs 下的 Exprs 应该匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多