Neues Beispiel 3: Wiederholung: Verbindung der Teile

30.01.2017 07:31 Uhr
#include <iostream>
#include <string.h>

using namespace std;
#include <fstream>

#include "ntoken3.h"

ClElement *verarbeite(ifstream& datei);
enum ezustand {direktive, element, attribute, abhaengigElement,
               abhaengigAttribute, noise};

int main()
{
char dateiname[100];
ifstream eingabe;
ClToken *token;
ClElement *jetzt=NULL, *wurzel;

cout << "DTD-Dateiname: " << endl;
cin >> dateiname;
eingabe.open(dateiname);

wurzel=verarbeite(eingabe);
for (jetzt=wurzel;jetzt!=NULL;jetzt=jetzt->getNext())
    jetzt->druckeElement(0,wurzel);
eingabe.close();

cout << "DTD erfolgreich geladen." << endl;

// -----------------------------------

cout << "XML-Dateiname:" << endl;
cin >> dateiname;
eingabe.open(dateiname);

token=new ClToken;

if (token->getToken(eingabe,NULL,wurzel)!=0) token->druckeToken(1);
eingabe.close();
}

ClElement *verarbeite(ifstream& datei)
{
char zeichen, letztes;
char puffer[100];
int zaehler;
enum ezustand zustand = noise;
ClElement *jetzt=NULL, *wurzel=NULL, *neu;

for (datei.get(zeichen);!datei.eof();datei.get(zeichen))
    {
    switch(zeichen)
       {
    case '<':
       zustand=direktive;
       zaehler=0;
       break;
    case '>':
       if (letztes!=' ')
          {
          puffer[zaehler]='\0';
          switch(zustand)
             {
          case abhaengigElement:
	     jetzt->addTag(puffer);
             break;
          case abhaengigAttribute:
             jetzt->addAttribute(puffer);
             break;
          case element:
             neu=new ClElement(puffer);
	     if (jetzt!=NULL) jetzt->setNext(neu);
	     else wurzel=neu;
	     jetzt=neu;
	     zustand=abhaengigElement;
             break;
	     }
          }
       zustand=noise;
       break;
    case ' ':
       if (letztes==' ') continue;
       puffer[zaehler]='\0';
       zaehler=0;
       switch(zustand)
          {
       case direktive:
          if (!strcmp(puffer,"!ELEMENT")) zustand=element;
          else if (!strcmp(puffer,"!ATTLIST")) zustand=attribute;
          else
	     {
	     cout << endl << "Diese Direktive verstehe ich nicht: " << puffer;
	     zustand=noise;
	     }
          break;
       case element:
          neu=new ClElement(puffer);
	  if (jetzt!=NULL) jetzt->setNext(neu);
	  else wurzel=neu;
	  jetzt=neu;
	  zustand=abhaengigElement;
          break;
       case attribute:


          if (wurzel==NULL) neu=NULL;

          else neu=wurzel->sucheElement(puffer,wurzel);
          if (neu==NULL)
             {
             cout << endl << "Es gibt kein Element mit dem Namen: " << puffer << endl;
             zustand=noise;
             }
          else
             {
             zustand=abhaengigAttribute;
             jetzt=neu;
             }
          break;
       case abhaengigElement:
          jetzt->addTag(puffer);
          break;
       case abhaengigAttribute:
          jetzt->addAttribute(puffer);
          break;
	  }
       break;
    default:
       if (zustand!=noise) puffer[zaehler] = zeichen;
       zaehler++;
       break;
       }
    letztes=zeichen;
    }

return wurzel;
}

Token Bibliothek

#include <iostream>

using namespace std;
#include <fstream>
#include <string.h>
#include "ntoken3.h"

ClToken::ClToken()
{
*tokenName='\0';
tokenChild=NULL;
tokenSibling=NULL;
tokenInhalt=new char[1];
*tokenInhalt='\0';
}

int  ClToken::getToken(
ifstream              &datei,
ClElement                   *element,
ClElement                           *wurzel)
{
int zaehler;
enum zustand zustand;
char zeichen;

char *ziel, *quelle;

char puffer[100];
ClToken *child;
int isChild;

cleanToken();

for (zaehler=0;;)
    {
    datei.get(zeichen);
    if (datei.eof())
       {
       if (*tokenName == '\0' && tokenChild == NULL && tokenInhalt == NULL)
          return fillToken(0);
       return fillToken(1);
       }
    switch(zeichen)
       {
    case '<':
       datei.get(zeichen);
       if (zeichen=='/')
          {
          zustand = istEndTag;
          if (zaehler!=0)
             {
             puffer[zaehler]='\0';
             tokenInhalt = new char[zaehler+1];
             strcpy(tokenInhalt,puffer);
             }
          }
       else
          {
          datei.putback(zeichen);
          if (*tokenName!='\0')
             {
             datei.putback('<');
	     if (tokenChild==NULL)
	        {
                tokenChild=new ClToken;
                if (tokenChild->getToken(datei,element,wurzel)==0)
                   return fillToken(0);
		}
	     else
	        {
		for (child=tokenChild;;child=child->tokenSibling)
		    {
		    if (child->tokenSibling==NULL)
		       {
		       child->tokenSibling=new ClToken;
                       if (child->tokenSibling->getToken(datei,element,wurzel)==0)
		          return fillToken(0);
		       break;
		       }
		    }
		}
             }
          else zustand=istStartTag;
          }
       zaehler=0;
       break;
    case '>':
       puffer[zaehler]='\0';
       if (zustand==istEndTag)
          {
	  if (strcmp(tokenName,puffer))
	     {
	     cout << "Fehlerhaftes End Tag" << endl;
	     cout << "Erhalten: '" << puffer << "'; erwartet: '"
	          << tokenName << "'" << endl;
             return fillToken(0);   
	     }
	  return fillToken(1);
	  }
       if (zustand==istStartTag)
          {


          for (ziel=tokenName,quelle=puffer;*quelle!=' ' && *quelle!= '\0';
               ziel++,quelle++) *ziel=*quelle;
          *ziel='\0';
          if (!strcmp(tokenName,wurzel->getName())) element=wurzel;
          else
             {   
	     if (element==NULL) isChild=-1;
	     else isChild=element->elementIstErlaubt(tokenName);
	     if (isChild < 0)
	        {
	        cout << "Fehlerhaftes Start Tag: '" << tokenName << "'" << endl; 
                return fillToken(0);
                }
	     element=element->sucheElement(tokenName,wurzel);
             }
          att.getAttList(puffer,element);


          }
       zaehler=0;
       break;
    case '\n':
       break;
    default:
       puffer[zaehler]=zeichen;
       zaehler++;
       break;
       }
    }
}

int ClToken::fillToken(
int                    mode)
{
if (*tokenName=='\0')
   strcpy(tokenName,"Unbekanntes Element");
if (tokenInhalt==NULL)
   {
   tokenInhalt=new char[1];
   *tokenInhalt='\0';
   }

return mode;
}

void ClToken::cleanToken(void)
{
*tokenName='\0';
if (tokenChild!=NULL)
   {
   delete tokenChild;
   tokenChild=NULL;
   }
if (tokenInhalt!=NULL)
   {
   delete tokenInhalt;
   tokenInhalt=NULL;
   }
}

void ClToken::druckeToken(
int                       ebene)
{
ClToken *child;

druckeTokenEbene(ebene);
cout << "Token: " << name() << " - " << inhalt() << endl;
if (att.zahlAtt() > 0)
   {
   for (int i=0;i<att.zahlAtt();i++)
       {
       druckeTokenEbene(ebene);
       cout << "Attribut " << att.zeigeAttName(i) << " hat den Wert "
            << att.zeigeAttWert(i) << endl;
       }
   }
if (tokenChild!=NULL) tokenChild->druckeToken(ebene+1);
if (tokenSibling!=NULL) tokenSibling->druckeToken(ebene);
}

void ClToken::druckeTokenEbene(
int                            ebene)
{
while (ebene > 0)
      {
      cout << "| ";
      ebene = ebene - 1;
      }
}

Attribute Header

#include "nelement3.h"

class ClattToken
   {
private:
   int anzahlAtt;
   char *attName[10];
   char *attValue[10];
public:

   int getAttList(char *eingabe,ClElement *element);


   char *zeigeAttName(int id) {return attName[id];}
   char *zeigeAttWert(int id) {return attValue[id];}
   int zahlAtt() {return anzahlAtt;}
   };

Attribute Bibliothek

#include <iostream>
#include <string.h>

using namespace std;
#include <fstream>
#include "natt3.h"

int ClattToken::getAttList(
char                      *eingabe,

ClElement                         *element)

{
char puffer[100];
int zaehler;
enum attzustand { zwischenTags, inNamen, erwarteAttributNamen, erwarteAttributWert,
               verarbeiteAttributWert} ;
enum attzustand zustand;

for (zaehler=0,zustand=inNamen,anzahlAtt=0;*eingabe!='\0';
     eingabe = eingabe + 1)
    {
   switch(*eingabe)
      {
   case ' ':
      if (zustand == inNamen)
         {
         zustand = erwarteAttributNamen;
         *eingabe='\0';
         zaehler=0;
         }
      else if (zustand == verarbeiteAttributWert)
         {
         puffer[zaehler] = *eingabe;
         zaehler++;
         }
      break;

   case '=':
      if (zustand == erwarteAttributNamen)
         {
         zustand = erwarteAttributWert;
         puffer[zaehler] = '\0';

         if (element->attributeIstErlaubt(puffer)<0)
            cout << endl << "Das Attribut " << puffer << " ist hier nicht erlaubt" << endl;


         attName[anzahlAtt] = new char[zaehler+1];
         strcpy(attName[anzahlAtt],puffer);
         zaehler=0;
         }
      else if (zustand == verarbeiteAttributWert)
         {
         puffer[zaehler] = *eingabe;
         zaehler++;
         }
      else cout << "Fehlerhaftes Zeichen! '='" << endl;
      break;

   case '"':
      if (zustand == erwarteAttributWert) 
         {
         zustand = verarbeiteAttributWert;
         zaehler = 0;
         }
      else if (zustand == verarbeiteAttributWert)
         {
         zustand = erwarteAttributNamen;
         puffer[zaehler] = '\0';
         attValue[anzahlAtt] = new char[zaehler+1];
         strcpy(attValue[anzahlAtt],puffer);
         zaehler=0;
         anzahlAtt++;
         }
      else cout << "Fehlerhaftes Zeichen! '\"'" << endl;
      break;

   default:
      if (zustand >= erwarteAttributNamen)
         {
         puffer[zaehler] = *eingabe;
         zaehler++;
         }
      break;
      }
   }

return 1;
}

Dateien: Beispiel 3

Schlagwörter: