如何删除重复和筛选XSL中的特定内容?

时间:2017-02-09 20:51:37

标签: xml xslt

我是xsl初学者,我一直试图让这个工作几天,但我遇到了一些问题。我做了一些研究并尝试了一些不同的解决方案,但我似乎无法做到正确。使用xsl 1.0和指定的输入,我需要删除重复项,并且还能够过滤特定的关键字。

这是输入:

<vce>
<document>
    <content name="title">X</content>
    <content name="description">
        <content name="h3">A</content>
        <content name="h3">B</content>
        <content name="h3">C</content>
        <content name="h3">A</content>
        <content name="h3">B</content>
        <content name="h3">C</content>
        <content name="h3">D</content>
        <content name="h3">E</content>
        <content name="h3">F</content>
        <content name="h3">G</content>
    </content>
</document>
</vce>

在说明中,我只能接受A,B和C,但也需要确保没有重复。因此我想要的输出应该是:

<vce>
<document>
    <content name="title">X</content>
    <content name="description">
        <content name="h3">A</content>
        <content name="h3">B</content>
        <content name="h3">C</content>
    </content>
</document>
</vce>

这就是我目前正在使用的内容:

<xsl:template match="/">
  <vce>
    <document>
      <content name="title">
        <xsl:for-each select="//document/content[@name='title']">
          <xsl:value-of select="." />
        </xsl:for-each>
      </content>

      <content name="description">
        <xsl:for-each select="//document/content[@name='h3']">
          <xsl:if test="not(preceding::document[content[@name='h3']/text() = current()/content[@name='h3']/text()])">
            <content name="h3">
              <xsl:value-of select="." />
            </content>
          </xsl:if>
        </xsl:for-each>
      </content>
    </document>
  </vce>
 </xsl:template>

提前感谢你们这些人的努力!

1 个答案:

答案 0 :(得分:0)

由于您输入的大量输入未在输出中发生变化,因此我默认以identity transform开始按原样复制所有内容。然后,您可以添加模板以覆盖需要的身份转换。

您还希望使用Muenchian Method分组来删除重复项。

您的输入是超级基本的,所以希望这可以与您的实际数据一起使用。

XML输入

<vce>
    <document>
        <content name="title">X</content>
        <content name="description">
            <content name="h3">A</content>
            <content name="h3">B</content>
            <content name="h3">C</content>
            <content name="h3">A</content>
            <content name="h3">B</content>
            <content name="h3">C</content>
            <content name="h3">D</content>
            <content name="h3">E</content>
            <content name="h3">F</content>
            <content name="h3">G</content>
        </content>
    </document>
</vce>

XSLT 1.0

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

  <xsl:key name="desc" match="content[@name='description']/content" use="."/>

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

  <xsl:template match="content[@name='description']">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:for-each select="content[.='A' or .='B' or .='C']
        [count(.|key('desc',.)[1])=1]">
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

<强>输出

<vce>
   <document>
      <content name="title">X</content>
      <content name="description">
         <content name="h3">A</content>
         <content name="h3">B</content>
         <content name="h3">C</content>
      </content>
   </document>
</vce>

这是另一个可能更容易管理&#34;允许&#34;元件。

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

  <xsl:param name="allowed" select="'|Step A.|Step B.|Step C.|'"/>

  <xsl:key name="desc" match="content[@name='description']/content" use="."/>

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

  <xsl:template match="content[@name='description']">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:for-each select="content[contains($allowed,concat('|',normalize-space(),'|'))]
        [count(.|key('desc',.)[1])=1]">
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>