English 中文(简体)
Deleting xml nodes using xslt
原标题:

Does anyone know how to copy only the first n nodes in a xml file and delete the rest using xslt? So say I only want to copy the first 10 nodes and delete the rest of the nodes that belong to the same parent.

问题回答

You should just remove them from your result set, as:

<!-- note you must to encode  greater than  and  lower than  characters -->
<xsl:for-each select="parent/nodes[position() &lt;= 10]">
    ...
</xsl:for-each>

Add the following template to the identity transform:

<xsl:template match="/*/*[position() &lt; 11]"/>

How it works: The identity transform copies any node it matches to the result document, recursively. But the match criteria on the identity transform have the lowest possible priority; if a node is matched by any template with a higher priority, that template will be used instead. (The priority rules are obscure, but they re so well designed that you rarely need to know about them; generally speaking, if a node is matched by two templates, XSLT will select the template whose pattern is more specific.)

In this case, we re saying that if a node is an element that s a child of the top-level element (the top level element is the first element under the root, or /*, and its child elements are thus /*/*) and its position in that list of nodes is 11 or higher, it shouldn t be copied.

Edit:

Oof. Everything about the above is correct except for the most important thing. What I wrote will copy every child of the top-level element except for the first ten.

Here s a complete (and correct) version of the templates you ll need:

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

<xsl:template match="/*/*[position() &gt; 10]"/>

That s it. The first template copies everything that s not matched by the second template. The second template matches all elements after the first 10 and does nothing with them, so they don t get copied to the output.

Sorry the code didn t paste properly below. Here is what it should be:

    <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>
    <xsl:template match="inner"/>    
    <xsl:template match="/*/*[position() &lt; 11]">
<xsl:call-template name="identity"/>  
    </xsl:template>

Use the identity transform, which will copy the source tree to the output tree, and add a template to exclude the elements you want to eliminate. Then, as you don t want to eliminate all of them but only those after the first ten, add one final template for the special ones that are to be allowed through, based on their position:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="inner"/>

  <xsl:template match="inner[position() &lt; 11]">
    <xsl:call-template name="identity"/>
  </xsl:template>

</xsl:stylesheet>

to be used with the XML

<?xml version="1.0" encoding="UTF-8"?>
<outer>
  <inner foo="1"/>
  <inner foo="2"/>
  <inner foo="3"/>
  <inner foo="4"/>
  <inner foo="5"/>
  <inner foo="6"/>
  <inner foo="7"/>
  <inner foo="8"/>
  <inner foo="9"/>
  <inner foo="10"/>
  <inner foo="11"/>
  <inner foo="12"/>
  <inner foo="13"/>
  <inner foo="14"/>
</outer>




相关问题
how to represent it in dtd?

I have two element action and guid. guid is a required field when action is add. but when action is del it will not appear in file. How to represent this in dtd ?

.Net application configuration add xml-data

I need to add xml-content to my application configuration file. Is there a way to add it directly to the appSettings section or do I need to implement a configSection? Is it possible to add the xml ...

XStream serializing collections

I have a class structure that I would like to serialize with Xstream. The root class contains a collection of other objects (of varying types). I would like to only serialize part of the objects that ...

MS Word splits words in its XML format

I have a Word 2003 document saved as a XML in WordProcessingML format. It contains few placeholders which will be dynamically replaced by an appropriate content. But, the problem is that Word ...

Merging an XML file with a list of changes

I have two XML files that are generated by another application I have no control over. The first is a settings file, and the second is a list of changes that should be applied to the first. Main ...

How do I check if a node has no siblings?

I have a org.w3c.dom.Node object. I would like to see if it has any other siblings. Here s what I have tried: Node sibling = node.getNextSibling(); if(sibling == null) return true; else ...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

热门标签