/**********************************************************************
*
*  projet   : DilibSxml
*  module   : SxPath
*  commande : SxmlCut
*  fichier  : SxmlCut.c
*  Auteur   : Jacques DUCLOY
*  Date     : December 2001
*  $Id: SxmlCut.c,v 1.2 2003/10/06 14:57:52 parmentf Exp $
*
***********************************************************************/
/**
   @file

   @brief SxmlCut command

   @section SxmlCutSYNOPSIS SYNOPSIS

   @code
   SxmlCut [ SxPath ][ SxPath ]... <inputFile >outputFile
   @endcode

   @section SxmlCutDESCRIPTION DESCRIPTION

   @p SxmlCut remove selected elements from each SxmlRecord of a stream.

   Selection mechanism uses @ref xpath.


   @section SxmlCutEXAMPLES EXAMPLES

   @code
   SxmlCut 1 doc/a
   @endcode

   on file
   
   @code
   001  <doc><a>aa</a><b>bb</b></doc>
   002  <doc><b>bb</b><c>cc</c></doc>
   @endcode

   will give

   @code
   <doc><b>bb</b></doc>
   <doc><b>bb</b><c>cc</c></doc>
   @endcode

   @see @ref xpath, SxPath (5), SxmlRecord (1)

   @author &copy; 2001 INIST-CNRS
   @author Jacques DUCLOY
           <DilibMaster@inist.fr>
   @since  December 2001

*/

#include "SxPath.h"
#include <stdlib.h>

/**************************

Processing is done in 2 steps:

  1 - matched nodes are marked with 'c' in SxmlNodeCustomType
  2 - marked nodes are freed

 *************************/

void cutMarkedChild(SxmlNode *n1)
{
  SxmlNode *n2, *n3;
  if(n1)
    {
      if ((n2=SxmlFirstChild(n1)))
	do
	  {
	    n3=SxmlNextSibling(n2);
	    if (SxmlNodeCustomType(n2)=='c')
	      {
		SxmlFree(n2);
	      }
	    else cutMarkedChild(n2);
	    n2=n3;
	  } while(n3);
    }
}

int main(int argc,
	 char **argv)
{
  SxmlNode *xpathCut;
  char *nextOptArg;
  int indice;
  SxPathResult *r1;
  SxmlNode *rec;

  xpathCut=SxmlElementCreate("union");
  indice=0;
   while(++indice<argc)
    {
      nextOptArg=argv[indice];
      if (strcmp(nextOptArg,"-T")==0)
	{
	  if (indice<argc)
	    {
	      DilibSetTraceLevel(atoi(argv[++indice]));
	    }
	  DilibSetTraceLevel(1);
	}
      else SxmlAppendChild(xpathCut, SxPathSxmlParseForRecord(nextOptArg));
    }

   if (DilibGetTraceLevel()>0)
     {
       SxmlPrint(xpathCut);
       putchar('\n');
     }
  
   r1=SxPathSetCompileOnSxml(xpathCut);

   while((rec=SxmlStdinNextRecord()))
     {
       SxmlNode *item;
       SxmlNode *listCutNode;

       if (DilibGetTraceLevel()>0)SxmlPrint(rec);

       listCutNode=SxPathSetResultListCreate(r1,rec);

       if (listCutNode)
	 {
	   SxmlReset(listCutNode);
	   while((item=SxmlNodeListNextNode(listCutNode)))
	     {
	       SxmlSetNodeCustomType(item,'c');
	     }
	   
	   SxmlReset(rec);
	   while((item=SxmlNextNode(rec)))
	     {
	       SxmlNode *item2;
	       SxmlSetNodeCustomType(item,'c');
	       SxmlReset(item);
	       while((item2=SxmlNextNode(item)))
		 {
		   if(SxmlNodeCustomType(item2)=='c')continue;
		   SxmlSetNodeCustomType(item,'\0');
		 }
	     }
	   cutMarkedChild(rec);
	 }
       SxmlPrint(rec);
     }
   return 0;
}

