XSLT / XPath:从所选内容中排除节点

时间:2012-03-27 01:36:30

标签: xml xslt xpath

我想选择符合特定条件的节点列表,在处理完这些节点后,我想选择其余节点。我怎么能在XSLT和XPath中做到这一点。

下面是场景,我有这个xml

<books>
<book name="Basic XML">
    <type>Educational</type>
    <grouping>A</grouping>
</book>
<book name="Basic XML">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>
<book name="Basic XSLT">
    <type>Educational</type>
    <grouping>A</grouping>
</book>
<book name="Basic XSLT">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>
<book name="Basic Java">
    <type>Educational</type>
    <grouping>A</grouping>
</book>
<book name="Basic Java">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>
<book name="Web Service">
    <type>Educational</type>
    <grouping>A</grouping>
</book>
<book name="C Programming">
    <type>Educational</type>
    <grouping>A</grouping>
</book>
</books>

1。选择所有<book>个节点<type>的“Tutorial”,下面是输出

<books>
<book name="Basic XML">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>   
<book name="Basic XSLT">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>
<book name="Basic Java">
    <type>Tutorial</type>
    <grouping>A</grouping>
</book>
</books>

2。然后选择其他<book>个节点没有<type>的“Tutorial”,并且与#1中选择的@name不同<books> <book name="Web Service"> <type>Educational</type> <grouping>A</grouping> </book> <book name="C Programming"> <type>Educational</type> <grouping>A</grouping> </book> </books> ,输出仅为:

{{1}}

2 个答案:

答案 0 :(得分:1)

对于第一个查询:

<xsl:apply-templates select="/books/book[type='Tutorial']"/>

对于第二个查询:

<xsl:apply-templates select="/books/book[type!='Tutorial']"/>

然后你需要适当的模板来处理它们:

<xsl:template match="/books/book[type='Tutorial']">
   Do Something...
</xsl:template>

最后一部分是检查当前节点是否也有一个教程节点

<xsl:template match="/books/book[type!='Tutorial']">
   <xsl:variable name="bookname">
      <xsl:value-of select="@name"/>
   </xsl:variable>
   <xsl:if test="count('/books/book[@name=$bookname and type='Tutorial']')=0">
      Do Something...
   </xsl:if>
</xsl:template>

答案 1 :(得分:0)

这是一个完整的解决方案

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <xsl:variable name="vTutBooks" select="book[type = 'Tutorial']"/>
  <books>
   <xsl:apply-templates select="$vTutBooks"/>
  </books>

  <books>
   <xsl:apply-templates select=
   "book[not(type = 'Tutorial')
       and
         not(@name = $vTutBooks/@name)
        ]"/>
  </books>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时

<books>
    <book name="Basic XML">
        <type>Educational</type>
        <grouping>A</grouping>
    </book>
    <book name="Basic XML">
        <type>Tutorial</type>
        <grouping>A</grouping>
    </book>
    <book name="Basic XSLT">
        <type>Educational</type>
        <grouping>A</grouping>
    </book>
    <book name="Basic XSLT">
        <type>Tutorial</type>
        <grouping>A</grouping>
    </book>
    <book name="Basic Java">
        <type>Educational</type>
        <grouping>A</grouping>
    </book>
    <book name="Basic Java">
        <type>Tutorial</type>
        <grouping>A</grouping>
    </book>
    <book name="Web Service">
        <type>Educational</type>
        <grouping>A</grouping>
    </book>
    <book name="C Programming">
        <type>Educational</type>
        <grouping>A</grouping>
    </book>
</books>

产生了想要的正确结果

<books>
   <book name="Basic XML">
      <type>Tutorial</type>
      <grouping>A</grouping>
   </book>
   <book name="Basic XSLT">
      <type>Tutorial</type>
      <grouping>A</grouping>
   </book>
   <book name="Basic Java">
      <type>Tutorial</type>
      <grouping>A</grouping>
   </book>
</books>
<books>
   <book name="Web Service">
      <type>Educational</type>
      <grouping>A</grouping>
   </book>
   <book name="C Programming">
      <type>Educational</type>
      <grouping>A</grouping>
   </book>
</books>