Guest User

Untitled

a guest
Dec 7th, 2010
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 4.96 KB | None | 0 0
  1. %**********************************************************************
  2. %   XML PARSER AND VALIDATOR (Version 1.0)
  3. %
  4. %   HOW TO USE:
  5. %       get_file_as_list(+FileName,-L),document(NAME,ATTR,CHILDREN,ENCODING,L,[]).
  6. %
  7. %   If the document is valid, the above query will return the structure of the document
  8. %   If the document is invalid, the document/4 DCG will fail
  9. %
  10. %   Current support for the following node types:
  11. %       Elements
  12. %       Attributes
  13. %       CDATA sections
  14. %       comments <!--  ... -->
  15. %       processing instructions <? ... ?>
  16. %
  17. %
  18. %   An XML element will have the following structure:
  19. %       (NAME,ATTRIBUTES,CHILDREN)
  20. %   where ATTRIBUTES is a list of the form:
  21. %       [(attr1,value1),(attr2,value2), ... ,(attrn,valuen)]
  22. %   and CHILDREN is a list of the form:
  23. %       [(NAME1,TYPE1),(NAME2,TYPE2), ... ,(NAMEN,TYPEN)]
  24. %   where:
  25. %       TYPE represents the node type, i.e.
  26. %       TYPE = 1 means element node
  27. %       TYPE = 8 means comment node
  28. %       TYPE = 4 means CDATA section node
  29. %       TYPE = 7 means processing instruction node
  30. %       TYPE = 3 means text node
  31. %   The node types are according to the DOM type designations.
  32. %
  33. %   Examples:
  34. %       (a,[],[]) translates to:
  35. %       <a/>
  36. %
  37. %       (a,[(a1,'1'),(a2,'x')],[(text,3)]) translates to:
  38. %       <a a1='1' a2='x'>text</a>
  39. %      
  40. %       (a,[],[(b,[],[])]) translates to:
  41. %       <a><b/></a>
  42. %**********************************************************************
  43. get_file_as_list(L) :- get_file_as_list('xmltest.xml', L).
  44.  
  45. get_file_as_list(Filename, L) :-
  46.     open(Filename, read, Stream),
  47.     get_contents(Stream, L),
  48.     close(Stream).
  49.    
  50. get_contents(Stream, []) :- at_end_of_stream(Stream), !.
  51. get_contents(Stream, [CharCode|Contents]) :-
  52.     get_char(Stream, Char),
  53.     char_code(Char,CharCode),
  54.     get_contents(Stream, Contents).
  55.  
  56. document(NAME,ATTR,CHILDREN,ENCODING) --> xmlProlog(ENCODING), spn, element(NAME,ATTR,CHILDREN).
  57.  
  58. xmlDoctype([]) --> [].
  59. xmlProlog(ENCODING) --> lt, "?", spn, "xml", sp, versionInfo, sp, encodingDecl(ENCODING), spn, "?", gt.
  60. xmlProlog(ENCODING) --> lt, "?", spn, "xml", sp, versionInfo, sp, encodingDecl(ENCODING), sp, sDecl, spn, "?", gt.
  61. xmlProlog([]) --> [].
  62. versionInfo --> "version", spn, eq, spn, quot, "1.0", quot.
  63. versionInfo --> "version", spn, eq, spn, apos, "1.0", apos.
  64. encodingDecl(ENCODING) --> "encoding", spn, eq, spn, quot, textword(ENCODING), quot.
  65. encodingDecl(ENCODING) --> "encoding", spn, eq, spn, apos, textword(ENCODING), apos.
  66. sDecl --> "standalone", spn, eq, spn, quot, yesNo, quot.
  67. sDecl --> "standalone", spn, eq, spn, apos, yesNo, apos.
  68. yesNo --> "yes".
  69. yesNo --> "no".
  70.  
  71. element(NAME,ATTRLIST,CHILDREN) --> starttag(NAME,ATTRLIST), nodelist(CHILDREN), endtag(NAME).
  72. element(NAME,ATTRLIST,[]) --> solotag(NAME,ATTRLIST).
  73. element(NAME,ATTRLIST,[]) --> starttag(NAME,ATTRLIST), endtag(NAME).
  74.  
  75. nodelist([(NAME,TYPE)|T]) --> node(NAME,TYPE), nodelist(T).
  76. nodelist([]) --> { ! }.
  77.  
  78. node((NAME,ATTRLIST,CHILDREN),1) --> element(NAME,ATTRLIST,CHILDREN).
  79. node(X,8) --> comment(X).
  80. node(X,4) --> cdata(X).
  81. node(X,7) --> pi(X).
  82. node(X,3) --> textword(X).
  83.  
  84. docTypeDecl(DECL) --> lt, "!DOCTYPE", spn, textword(DECL), spn, gt.
  85. comment(TEXT) --> lt, "!--", spn, textword(TEXT), spn, "--", gt.
  86. cdata(CDATA) --> lt, "![CDATA[", spn, textword(CDATA), spn, "]]", gt.
  87. pi(PI) --> lt, "?", spn, textword(PI), spn, "?", gt.
  88.  
  89. starttag(NAME,ATTRLIST) --> lt, spn, nameword(NAME), sp, attributelist(ATTRLIST), spn, gt.
  90. starttag(NAME,[]) --> lt, spn, nameword(NAME), spn, gt.
  91. endtag(NAME) --> lt, "/", spn, nameword(NAME), spn, gt.
  92. solotag(NAME,ATTRLIST) --> lt, spn, nameword(NAME), sp, attributelist(ATTRLIST), spn, "/", gt.
  93. solotag(NAME,[]) --> lt, spn, nameword(NAME), spn, "/", gt.
  94.  
  95. attributelist([(N,V)|T]) --> attribute(N,V), spn, attributelist(T).
  96. attributelist([]) --> [].
  97.  
  98. attribute(NAME,VALUE) --> nameword(NAME), spn, eq, spn, quot, textword(VALUE), quot.
  99. attribute(NAME,VALUE) --> nameword(NAME), spn, eq, spn, apos, textword(VALUE), apos.
  100.  
  101. nameword(WORD) --> { var(WORD), ! },
  102.    namechars(CHARS), { atom_codes(WORD, CHARS) }.
  103. nameword(WORD) --> { nonvar(WORD) },
  104.    { atom_codes(WORD, CHARS) }, namechars(CHARS).
  105.  
  106. textword(WORD) --> { var(WORD), ! },
  107.    textchars(CHARS), { atom_codes(WORD, CHARS) }.
  108. textword(WORD) --> { nonvar(WORD) },
  109.    { atom_codes(WORD, CHARS) }, textchars(CHARS).
  110.  
  111. namechars([X|Y]) --> namechar(X), namechars(Y).
  112. namechars([X]) --> namechar(X).
  113. textchars([X|Y]) --> textchar(X), textchars(Y).
  114. textchars([X]) --> textchar(X).
  115.  
  116. sp --> spchar(_).
  117. sp --> spchar(_), sp.
  118. spn --> sp.
  119. spn --> [].
  120.  
  121. namechar(X) --> [X], { is_namechar(X) }.
  122. textchar(X) --> [X], { is_textchar(X) }.
  123. spchar(X) --> [X], { member(X," \n\t"), ! }.
  124.  
  125. is_letter(X) :- X >= 0'a, X =< 0'z, !.
  126. is_letter(X) :- X >= 0'A, X =< 0'Z, !.
  127. is_digit(X) :- X >= 0'0, X =< 0'9, !.
  128. is_namechar(X) :- is_letter(X), !.
  129. is_namechar(X) :- is_digit(X), !.
  130. is_namechar(X) :- member(X,"_:.-"), !.
  131. is_textchar(X) :- is_namechar(X), !.
  132. is_textchar(X) :- member(X," \n\t`~!@#$%^&*()-=\\_+|[]{};:,./?"), !.
  133.  
  134. quot --> "\"".
  135. apos --> "\'".
  136. lt --> "<".
  137. gt --> ">".
  138. eq --> "=".
Advertisement
Add Comment
Please, Sign In to add comment