Xml 如何在XSL中删除重复项并筛选特定内容?

Xml 如何在XSL中删除重复项并筛选特定内容?,xml,xslt,Xml,Xslt,我是一名xsl初学者,几天来我一直在努力让它工作,但我遇到了一些问题。我做了一些研究,并尝试了一些不同的解决方案,但我似乎做不好。使用XSL1.0和指定的输入,我需要删除重复项,并且能够筛选特定的关键字 以下是输入: <vce> <document> <content name="title">X</content> <content name="description"> <content nam

我是一名xsl初学者,几天来我一直在努力让它工作,但我遇到了一些问题。我做了一些研究,并尝试了一些不同的解决方案,但我似乎做不好。使用XSL1.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>

X
A.
B
C
A.
B
C
D
E
F
G
在描述中,我只能接受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>

X
A.
B
C
这就是我目前正在处理的问题:

<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>


提前感谢大家的努力

由于您的许多输入在输出中没有改变,因此我将从一个开始,按照默认情况复制所有内容。然后,您可以在需要时添加模板以覆盖标识转换

您还需要使用分组的方式来删除重复项

您的输入是超基本的,所以希望这将与您的实际数据一起工作

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>
<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>

X
A.
B
C
A.
B
C
D
E
F
G
XSLT1.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 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>
<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>

X
A.
B
C
下面是另一个版本,它可能会使管理“允许的”元素变得更容易

<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>


我是一名xsl初学者,几天来我一直在努力让它工作……XSLT的试用版在哪里?XSLT的哪个版本?我正在使用1.0版。如果我要查找的内容比a、B和C更复杂,那又如何呢,如果我正在查找任何包含关键字“step”或后跟“.”(即“1”)的数字的文本,will@MarkB-是的,应该仍然可以正常工作。您可能希望使用
normalize-space()
而不是仅使用
,尽管这样任何无关的空格都不会影响比较。示例:
normalize-space()=“步骤1”。
我还添加了另一个示例,该示例使用xsl:param保存所比较的内容。这样可能会更容易管理。这至少应该是一个好的开始。