【问题标题】:XSL eliminating elementsXSL 消除元素
【发布时间】:2015-02-12 07:12:13
【问题描述】:

我有这个 xml 文档:

<tags>
<w lemme="déclaration" pos="NOM">Déclaration</w>
<w lemme="du" pos="PRP:det">des</w>
<w lemme="droit" pos="NOM">droits</w>
<w lemme="de" pos="PRP">de</w>
<w lemme="le" pos="DET:ART">l'</w>
<w lemme="homme" pos="NOM">homme</w>
<w lemme="et" pos="KON">et</w>
<w lemme="," pos="PUN">,</w>
...
</tags>

我正在尝试使用 xsl 过滤掉文章和标点符号。像这里 ,del'。因此,我制作了以下样式表,该样式表有效,但将我的所有条件推广到所有标签,包括标签 。

<xsl:template match="*">
<xsl:choose>
<xsl:when test="contains(@pos,'PUN')"></xsl:when>
<xsl:when test="contains(@pos,'PRP')"></xsl:when>
<xsl:when test="contains(@pos,'DET')"></xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:attribute name="lemme">
<xsl:value-of select="@lemme"/>
</xsl:attribute>
<xsl:attribute name="pos">
<xsl:value-of select="@pos"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

我有这个结果:

<tags lemme="" pos="">
<w lemme="déclaration" pos="NOM">Déclaration</w>
<w lemme="droit" pos="NOM">droits</w>
<w lemme="homme" pos="NOM">homme</w>
<w lemme="et" pos="KON">et</w>
<w lemme="citoyen" pos="NOM">citoyen</w>

所以它只显示我感兴趣的行,只是我不希望它在第一行的 标记中添加 lemme="" pos="" 。我应该在 xsl 中进行什么更改以使其仅使用 标签。我尝试了 但它没有生成有效的 xml。请帮忙?

【问题讨论】:

  • 您能重新格式化您的问题吗?您的代码块不可读...
  • 是的,对不起,我觉得现在好多了

标签: xml xslt


【解决方案1】:

你应该使用标准的身份转换,也就是这个模板:

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

您始终可以使用它来将所有内容从源复制到输出。异常由额外的模板处理,如下所示:

<xsl:template match="w[contains(@pos,'PUN')]
                    |w[contains(@pos,'PRP')]
                    |w[contains(@pos,'DET')]"/>

什么都不做。它只是匹配不需要的元素并防止身份转换模板匹配和复制它们。完整的样式表如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="w[contains(@pos,'PUN')]
                      |w[contains(@pos,'PRP')]
                      |w[contains(@pos,'DET')]"/>
</xsl:stylesheet>

【讨论】:

  • +1 用于建议基于身份转换的解决方案,减少复制样板。
【解决方案2】:

有几种方法可以解决这个问题,但增加已有内容的一种方法是让一个规则匹配并输出标签元素,然后应用仅匹配 w 元素的第二个模板

首先,将此模板添加到您拥有的模板之前:

<xsl:template match="/tags">
<xsl:copy>
<xsl:apply-templates select="w"/>
</xsl:copy>
</xsl:template>

对于第二点,将您当前的模板更改为:

<xsl:template match="w">

为清楚起见,这里是完整的样式表:

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

    <xsl:template match="/tags">
        <xsl:copy>
            <xsl:apply-templates select="w"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="w">
        <xsl:choose>
            <xsl:when test="contains(@pos,'PUN')"></xsl:when>
            <xsl:when test="contains(@pos,'PRP')"></xsl:when>
            <xsl:when test="contains(@pos,'DET')"></xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:attribute name="lemme">
                        <xsl:value-of select="@lemme"/>
                    </xsl:attribute>
                    <xsl:attribute name="pos">
                        <xsl:value-of select="@pos"/>
                    </xsl:attribute>
                    <xsl:apply-templates/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

这会产生预期的结果:

<?xml version="1.0" encoding="utf-8"?>
<tags>
    <w lemme="déclaration" pos="NOM">Déclaration</w>
    <w lemme="droit" pos="NOM">droits</w>
    <w lemme="homme" pos="NOM">homme</w>
    <w lemme="et" pos="KON">et</w>
</tags>

希望这会有所帮助。

【讨论】:

  • 感谢您的回答。问题是我确实希望它们成为输出的一部分,但只在 标签中,但它还在第一个母标签 . 中添加属性
  • 抱歉,我回复得太快了,错过了那个细节。正在更新答案。
  • 好吧,我真的不能使用两个不同的
  • 我还尝试在我之前添加该块并将我当前的匹配*更改为“w”但 xml 甚至无效
  • 您在 w 元素中的匹配绝不会受到引入第二个模板的影响。为清楚起见,我添加了完整的样式表,并根据您列出的输入添加了 XSLT 转换器产生的输出。
猜你喜欢
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 2012-10-01
  • 2014-03-12
相关资源
最近更新 更多