Parser une DTD avec XmlTextReader
Bonjour,
Comme l'indique le titre du post, j'aimereai savoir s'il est possible de parser une DTD avec un XmlTextReader.
Un peu plus de précision si besoin est. J'ai le fichier xml suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE PROJECT SYSTEM 'leon/conf/dtd/leon.dtd'
[
<!-- Standard includes -->
<!ENTITY LEON SYSTEM 'leon/conf/xml/leon.xml'>
<!-- Root include -->
<!ENTITY ROOT SYSTEM 'leon/contrib/hotel/info/rootEntities.xml'>
<!ENTITY NAVIGATION SYSTEM 'leon/contrib/hotel/info/navigationTree.xml'>
<!ENTITY location SYSTEM 'leon/contrib/hotel/info/location.xml'>
<!-- Classes includes -->
<!ENTITY city SYSTEM 'leon/contrib/hotel/info/city.xml'>
<!ENTITY client SYSTEM 'leon/contrib/hotel/info/client.xml'>
<!ENTITY current_reservation SYSTEM 'leon/contrib/hotel/info/current_reservation.xml'>
<!ENTITY establishment SYSTEM 'leon/contrib/hotel/info/establishment.xml'>
<!ENTITY manager SYSTEM 'leon/contrib/hotel/info/manager.xml'>
<!ENTITY province SYSTEM 'leon/contrib/hotel/info/province.xml'>
<!ENTITY reservation SYSTEM 'leon/contrib/hotel/info/reservation.xml'>
<!ENTITY room SYSTEM 'leon/contrib/hotel/info/room.xml'>
]>
<PROJECT id="HOTEL" name="HOTEL" rootAction="login_manager"
sessionBehavior="leon.contrib.hotel.behavior.HotelSessionBehavior">
<!-- Standard Leonardi declarations -->
&LEON;
<!-- Root declarations -->
&ROOT;
<!-- Locations -->
&location;
<!-- Classes declarations -->
&city;
&client;
&reservation;
¤t_reservation;
&establishment;
&manager;
&province;
&room;
<!-- Navigation Tree -->
&NAVIGATION;
</PROJECT> |
Le parsing de ce fichier (et tous ceux auquels il fait référence) se fait nickel. Le problème c'est que le fichier 'leon/conf/dtd/leon.dtd' n'est pas parsé. Or ce fichier contient un certain nombre de valeurs par défaut pour les champs présents dans les fichiers XML (valeurs que je dois absoluement récupérer).
Par la même occasion, je pense du coup que la validité de mes fichiers XML n'est pas vérifiée par rapport à ma DTD
Voici le code de la fonction de parsing (réalisée selon le modèle SAX):
_reader est une instance de XmlTextReader
_handler est une instance de ma classe d'handling
_resolver est une instance de ma classe de "résolution d'entités" (héritant de XmlResolver)
Seules les méthodes StartElement() et EndElement() sont implémenté pour le moment (je ne sais pour le moment pas trop quoi mettre dans les autres mais ca n'est immédiatement pas un problème)
Les classes Locator et Attribute sont des classes de mon programme (leur fonctionnement importe peu)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
public virtual void Parse()
{
Stack nsstack = new Stack();
Locator locator = new Locator();
SAXParseException saxException = new SAXParseException();
Attributes atts = new Attributes();
try
{
//_reader = new XmlTextReader(_stream);
//Init();
object nsuri = _reader.NameTable.Add(
"http://www.w3.org/2000/xmlns/");
_handler.StartDocument();
while (_reader.Read())
{
string prefix = "";
locator.LineNumber = _reader.LineNumber;
locator.ColumnNumber = _reader.LinePosition;
_handler.SetDocumentLocator(locator);
switch (_reader.NodeType)
{
case XmlNodeType.DocumentType :
while (_reader.MoveToNextAttribute())
{
Console.WriteLine("file:///" + _reader.Value.Replace('\\', '/'));
_resolver.GetEntity(new Uri("file:///" + _reader.Value.Replace('\\', '/')), null, null);
}
break;
case XmlNodeType.Element:
nsstack.Push(null); //marker
atts = new Attributes();
while (_reader.MoveToNextAttribute())
{
if (_reader.NamespaceURI.Equals(nsuri))
{
prefix = "";
if (_reader.Prefix == "xmlns")
{
prefix = _reader.LocalName;
}
nsstack.Push(prefix);
_handler.StartPrefixMapping(prefix, _reader.Value);
}
else
{
atts.AddAttribute(_reader.NamespaceURI, _reader.Name, _reader.Name, _reader.GetType().ToString(), _reader.Value);
}
}
_reader.MoveToElement();
_handler.StartElement(_reader.NamespaceURI, _reader.LocalName, _reader.Name, atts);
if (_reader.IsEmptyElement)
{
_handler.EndElement(_reader.NamespaceURI, _reader.LocalName, _reader.Name);
}
break;
case XmlNodeType.EndElement:
_handler.EndElement(_reader.NamespaceURI, _reader.LocalName, _reader.Name);
while (prefix != null)
{
_handler.EndPrefixMapping(prefix);
prefix = (string)nsstack.Pop();
}
break;
case XmlNodeType.Text:
_handler.Characters(_reader.Value.ToCharArray(), 0, _reader.Value.Length);
break;
case XmlNodeType.ProcessingInstruction:
_handler.ProcessingInstruction(_reader.Name, _reader.Value);
break;
case XmlNodeType.Whitespace:
char[] whiteSpace = _reader.Value.ToCharArray();
_handler.IgnorableWhitespace(whiteSpace, 0, 1);
break;
case XmlNodeType.Entity:
_handler.SkippedEntity(_reader.Name);
break;
case XmlNodeType.EntityReference:
_reader.ResolveEntity();
break;
}
} //While
_handler.EndDocument();
} //try
catch (Exception exception)
{
//
}
finally
{
if (_reader.ReadState != ReadState.Closed)
{
_reader.Close();
}
}
} |
Voilà j'espère que ca ne fait pas trop d'information et que vous aller pouvoir m'aider ^^