include XMLPL package.
This commit is contained in:
36
packages/xml/xml_example/bib.xml
Normal file
36
packages/xml/xml_example/bib.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<bib>
|
||||
<book year="1994">
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author><last>Stevens</last><first>W.</first></author>
|
||||
<publisher>Addison-Wesley</publisher>
|
||||
<price> 65.95</price>
|
||||
</book>
|
||||
|
||||
<book year="1992">
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author><last>Stevens</last><first>W.</first></author>
|
||||
<publisher>Addison-Wesley</publisher>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
|
||||
<book year="2000">
|
||||
<title>Data on the Web</title>
|
||||
<author><last>Abiteboul</last><first>Serge</first></author>
|
||||
<author><last>Buneman</last><first>Peter</first></author>
|
||||
<author><last>Suciu</last><first>Dan</first></author>
|
||||
<publisher>Morgan Kaufmann Publishers</publisher>
|
||||
<price>39.95</price>
|
||||
</book>
|
||||
|
||||
<book year="1999">
|
||||
<title>The Economics of Technology and Content for Digital TV</title>
|
||||
<editor>
|
||||
<last>Gerbarg</last><first>Darcy</first>
|
||||
<affiliation>CITI</affiliation>
|
||||
</editor>
|
||||
<publisher>Kluwer Academic Publishers</publisher>
|
||||
<price>129.95</price>
|
||||
</book>
|
||||
|
||||
</bib>
|
||||
|
15
packages/xml/xml_example/books.xml
Normal file
15
packages/xml/xml_example/books.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<chapter>
|
||||
<title>Data Model</title>
|
||||
<section>
|
||||
<title>Syntax For Data Model</title>
|
||||
</section>
|
||||
<section>
|
||||
<title>XML</title>
|
||||
<section>
|
||||
<title>Basic Syntax</title>
|
||||
</section>
|
||||
<section>
|
||||
<title>XML and Semistructured Data</title>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
95
packages/xml/xml_example/misc.pl
Normal file
95
packages/xml/xml_example/misc.pl
Normal file
@@ -0,0 +1,95 @@
|
||||
% Utility Predicates
|
||||
|
||||
% The following predicates are used in the puzzle solutions.
|
||||
% unique_solution( +Goal ) holds when Goal has one ground solution. Operationally,
|
||||
% Goal may produce several solutions, ("don't care" non-deterministically), but they
|
||||
% must all be identical (==).
|
||||
|
||||
unique_solution( Goal ) :-
|
||||
findall( Goal, Goal, [Solution|Solutions] ),
|
||||
same_solution( Solutions, Solution ),
|
||||
Solution = Goal.
|
||||
|
||||
same_solution( [], _Solution ).
|
||||
same_solution( [Solution0|Solutions], Solution ) :-
|
||||
Solution0 == Solution,
|
||||
same_solution( Solutions, Solution ).
|
||||
|
||||
% forall( +Enumerator, +Test ) is true if Enumerator and Test are goals and Test holds everywhere
|
||||
% that Enumerator does. NB: does not further instantiate arguments.
|
||||
|
||||
%% forall( Enumerator, Test ) :-
|
||||
%% \+ (call(Enumerator), \+ call(Test)).
|
||||
|
||||
% member( ?Element, ?List ) holds when Element is a member of List.
|
||||
member( H, [H|_] ).
|
||||
member( H, [_|T] ):-
|
||||
member( H, T ).
|
||||
|
||||
% select( ?Element, ?List0, ?List1 ) is true if List1 is equal to List1 with Element removed.
|
||||
|
||||
select( H, [H|T], T ).
|
||||
select( Element, [H|T0], [H|T1] ):-
|
||||
select( Element, T0, T1 ).
|
||||
|
||||
% memberchk( +Element, +List ) succeeds (once) if Element is a member of List.
|
||||
memberchk( Element, List ):-
|
||||
member( Element, List ),
|
||||
!.
|
||||
|
||||
% between( +Lower, +Upper, ?Index ) is true if Lower =< Index =< Upper. Two valid cases are
|
||||
% possible:
|
||||
% - Index is already instantiated to an integer so the checks on order are applied (test).
|
||||
% - Index is a logical variable so a series of alternative solutions is generated as the
|
||||
% monotonic sequence of values between Lower and Upper (non-deterministic generator).
|
||||
|
||||
%% between( Lower, Upper, Index ):-
|
||||
%% integer( Lower ),
|
||||
%% integer( Upper ),
|
||||
%% Lower =< Upper,
|
||||
%% ( integer( Index ) -> % Case 1: "test"
|
||||
%% Index >= Lower,
|
||||
%% Index =< Upper
|
||||
%% ; var( Index ) -> % Case 2: "generate".
|
||||
%% generate_between( Lower, Upper, Index )
|
||||
%% ).
|
||||
|
||||
generate_between( Lower, Upper, Index ) :-
|
||||
( Lower =:= Upper ->
|
||||
Index = Lower
|
||||
; Index = Lower
|
||||
; Next is Lower + 1,
|
||||
Next =< Upper,
|
||||
generate_between( Next, Upper, Index )
|
||||
).
|
||||
|
||||
% sum( +List, ?Sum ) holds when the List of numbers sum to Sum.
|
||||
|
||||
sum( [H|T], Sum ) :-
|
||||
sum1( T, H, Sum ).
|
||||
|
||||
sum1( [], Sum, Sum ).
|
||||
sum1( [H|T], Sum0, Sum ):-
|
||||
Sum1 is Sum0 + H,
|
||||
sum1( T, Sum1, Sum ).
|
||||
|
||||
% put_chars( +Chars ) if Chars is a (possibly empty) list of character codes and the
|
||||
% corresponding characters are written to the current output stream.
|
||||
|
||||
put_chars( [] ).
|
||||
put_chars( [Char|Chars] ) :-
|
||||
put( Char ),
|
||||
put_chars( Chars ).
|
||||
|
||||
% get_chars( ?Chars ) if Chars is a (possibly empty) list of character codes read
|
||||
% from the current input stream.
|
||||
|
||||
get_chars( Input ) :-
|
||||
get0( Char ),
|
||||
( Char > -1 ->
|
||||
Input = [Char|Chars],
|
||||
get_chars( Chars )
|
||||
; otherwise ->
|
||||
Input = []
|
||||
).
|
||||
|
32
packages/xml/xml_example/prices.xml
Normal file
32
packages/xml/xml_example/prices.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<prices>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>34.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>39.95</price>
|
||||
</book>
|
||||
</prices>
|
9
packages/xml/xml_example/q1.xml
Normal file
9
packages/xml/xml_example/q1.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
<bib>
|
||||
<book year="1994">
|
||||
<title>TCP/IP Illustrated</title>
|
||||
</book>
|
||||
<book year="1992">
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
</book>
|
||||
</bib>
|
11
packages/xml/xml_example/q10.xml
Normal file
11
packages/xml/xml_example/q10.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<results>
|
||||
<minprice title="Advanced Programming in the Unix environment">
|
||||
<price>65.95</price>
|
||||
</minprice>
|
||||
<minprice title="TCP/IP Illustrated">
|
||||
<price>65.95</price>
|
||||
</minprice>
|
||||
<minprice title="Data on the Web">
|
||||
<price>34.95</price>
|
||||
</minprice>
|
||||
</results>
|
35
packages/xml/xml_example/q11.xml
Normal file
35
packages/xml/xml_example/q11.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<bib>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</book>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Abiteboul</last>
|
||||
<first>Serge</first>
|
||||
</author>
|
||||
<author>
|
||||
<last>Buneman</last>
|
||||
<first>Peter</first>
|
||||
</author>
|
||||
<author>
|
||||
<last>Suciu</last>
|
||||
<first>Dan</first>
|
||||
</author>
|
||||
</book>
|
||||
<reference>
|
||||
<title>The Economics of Technology and Content for Digital TV</title>
|
||||
<affiliation>CITI</affiliation>
|
||||
</reference>
|
||||
</bib>
|
6
packages/xml/xml_example/q12.xml
Normal file
6
packages/xml/xml_example/q12.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<bib>
|
||||
<book-pair>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
</book-pair>
|
||||
</bib>
|
37
packages/xml/xml_example/q2.xml
Normal file
37
packages/xml/xml_example/q2.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<results>
|
||||
<result>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Abiteboul</last>
|
||||
<first>Serge</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Buneman</last>
|
||||
<first>Peter</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Suciu</last>
|
||||
<first>Dan</first>
|
||||
</author>
|
||||
</result>
|
||||
</results>
|
34
packages/xml/xml_example/q3.xml
Normal file
34
packages/xml/xml_example/q3.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<results>
|
||||
<result>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Abiteboul</last>
|
||||
<first>Serge</first>
|
||||
</author>
|
||||
<author>
|
||||
<last>Buneman</last>
|
||||
<first>Peter</first>
|
||||
</author>
|
||||
<author>
|
||||
<last>Suciu</last>
|
||||
<first>Dan</first>
|
||||
</author>
|
||||
</result>
|
||||
<result>
|
||||
<title>The Economics of Technology and Content for Digital TV</title>
|
||||
</result>
|
||||
</results>
|
31
packages/xml/xml_example/q4.xml
Normal file
31
packages/xml/xml_example/q4.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<results>
|
||||
<result>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
</result>
|
||||
<result>
|
||||
<author>
|
||||
<last>Abiteboul</last>
|
||||
<first>Serge</first>
|
||||
</author>
|
||||
<title>Data on the Web</title>
|
||||
</result>
|
||||
<result>
|
||||
<author>
|
||||
<last>Buneman</last>
|
||||
<first>Peter</first>
|
||||
</author>
|
||||
<title>Data on the Web</title>
|
||||
</result>
|
||||
<result>
|
||||
<author>
|
||||
<last>Suciu</last>
|
||||
<first>Dan</first>
|
||||
</author>
|
||||
<title>Data on the Web</title>
|
||||
</result>
|
||||
</results>
|
18
packages/xml/xml_example/q5.xml
Normal file
18
packages/xml/xml_example/q5.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
<books-with-prices>
|
||||
<book-with-prices>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<price-amazon>65.95</price-amazon>
|
||||
<price-bn> 65.95</price-bn>
|
||||
</book-with-prices>
|
||||
<book-with-prices>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<price-amazon>65.95</price-amazon>
|
||||
<price-bn>65.95</price-bn>
|
||||
</book-with-prices>
|
||||
<book-with-prices>
|
||||
<title>Data on the Web</title>
|
||||
<price-amazon>34.95</price-amazon>
|
||||
<price-bn>39.95</price-bn>
|
||||
</book-with-prices>
|
||||
</books-with-prices>
|
28
packages/xml/xml_example/q6.xml
Normal file
28
packages/xml/xml_example/q6.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<bib>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</book>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author>
|
||||
<last>Stevens</last>
|
||||
<first>W.</first>
|
||||
</author>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Abiteboul</last>
|
||||
<first>Serge</first>
|
||||
</author>
|
||||
<author>
|
||||
<last>Buneman</last>
|
||||
<first>Peter</first>
|
||||
</author>
|
||||
<et-al/>
|
||||
</book>
|
||||
</bib>
|
9
packages/xml/xml_example/q7.xml
Normal file
9
packages/xml/xml_example/q7.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
<bib>
|
||||
<book year="1992">
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
</book>
|
||||
<book year="1994">
|
||||
<title>TCP/IP Illustrated</title>
|
||||
</book>
|
||||
</bib>
|
10
packages/xml/xml_example/q8.xml
Normal file
10
packages/xml/xml_example/q8.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
<bib>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<author>
|
||||
<last>Suciu</last>
|
||||
<first>Dan</first>
|
||||
</author>
|
||||
</book>
|
||||
</bib>
|
5
packages/xml/xml_example/q9.xml
Normal file
5
packages/xml/xml_example/q9.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
<results>
|
||||
<title>XML</title>
|
||||
<title>XML and Semistructured Data</title>
|
||||
</results>
|
25
packages/xml/xml_example/reviews.xml
Normal file
25
packages/xml/xml_example/reviews.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
<reviews>
|
||||
<entry>
|
||||
<title>Data on the Web</title>
|
||||
<price>34.95</price>
|
||||
<review>
|
||||
A very good discussion of semi-structured database
|
||||
systems and XML.
|
||||
</review>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<price>65.95</price>
|
||||
<review>
|
||||
A clear and detailed discussion of UNIX programming.
|
||||
</review>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<price>65.95</price>
|
||||
<review>
|
||||
One of the best books on TCP/IP.
|
||||
</review>
|
||||
</entry>
|
||||
</reviews>
|
388
packages/xml/xml_example/xml_example.pl
Normal file
388
packages/xml/xml_example/xml_example.pl
Normal file
@@ -0,0 +1,388 @@
|
||||
/* Using xml.pl to solve XML Query Cases - An Example
|
||||
*
|
||||
* The following is a complete example to illustrate how the module can be used;
|
||||
* it exercises both the input and output parsing modes of xml_parse/[2,3], and
|
||||
* illustrates the use of xml_subterm/2 to access the nodes of a "document value
|
||||
* model". It's written for Quintus Prolog, but should port to other Prologs
|
||||
* easily.
|
||||
*
|
||||
* The entry-point of the program is the test/1 predicate.
|
||||
*
|
||||
* test( +QueryId ) executes a Prolog implementation of a Query from Use Case
|
||||
* "XMP": Experiences and Exemplars, in the W3C's XML Query Use Cases, which
|
||||
* "contains several example queries that illustrate requirements gathered from
|
||||
* the database and document communities".
|
||||
* <http://www.w3.org/TR/2002/WD-xmlquery-use-cases-20021115/#xmp>
|
||||
*
|
||||
* QueryId is one of q1<EFBFBD>q12 selecting which of the 12 use cases is executed.
|
||||
* The XML output is written to the file [QueryId].xml in the current directory.
|
||||
*
|
||||
* xml_pp/1 is used to display the resulting "document value model"
|
||||
% data-structures on the user output (stdout) stream.
|
||||
*/
|
||||
|
||||
:- use_module(library(lists),[append/3]).
|
||||
|
||||
test( Query ) :-
|
||||
xml_query( Query, ResultElement ),
|
||||
% Parse output XML into the Output chars
|
||||
xml_parse( Output, xml([], [ResultElement]) ),
|
||||
absolute_file_name( Query, [extensions([xml])], OutputFile ),
|
||||
% Write OutputFile from the Output list of chars
|
||||
tell( OutputFile ),
|
||||
put_chars( Output ),
|
||||
told,
|
||||
% Pretty print OutputXML
|
||||
write( 'Output XML' ), nl,
|
||||
xml_pp( xml([], [ResultElement]) ).
|
||||
|
||||
/* xml_query( +QueryNo, ?OutputXML ) when OutputXML is an XML Document Value Model
|
||||
* produced by running an example taken, identified by QueryNo from the XML Query
|
||||
* "XMP" use case.
|
||||
*/
|
||||
|
||||
% Q1: List books published by Addison-Wesley after 1991, including their year and
|
||||
% title.
|
||||
|
||||
xml_query( q1, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Publisher, publisher ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [year=Year], [Title]),
|
||||
(
|
||||
xml_subterm( Bibliography, element(book, Attributes, Content) ),
|
||||
xml_subterm( Content, Publisher ),
|
||||
xml_subterm( Publisher, Text ),
|
||||
text_value( Text, "Addison-Wesley" ),
|
||||
member( year=Year, Attributes ),
|
||||
number_codes( YearNo, Year ),
|
||||
YearNo > 1991,
|
||||
xml_subterm( Content, Title )
|
||||
),
|
||||
Books
|
||||
).
|
||||
|
||||
% Q2: Create a flat list of all the title-author pairs, with each pair enclosed
|
||||
% in a "result" element.
|
||||
|
||||
xml_query( q2, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(result, [], [Title,Author]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
xml_subterm( Book, Author )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q3: For each book in the bibliography, list the title and authors, grouped
|
||||
% inside a "result" element.
|
||||
|
||||
xml_query( q3, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(result, [], [Title|Authors]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
findall( Author, xml_subterm(Book, Author), Authors )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q4: For each author in the bibliography, list the author's name and the titles
|
||||
% of all books by that author, grouped inside a "result" element.
|
||||
|
||||
xml_query( q4, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall( Author, xml_subterm(Bibliography, Author), AuthorBag ),
|
||||
sort( AuthorBag, Authors ),
|
||||
findall(
|
||||
element(result, [], [Author|Titles]),
|
||||
(
|
||||
member( Author, Authors ),
|
||||
findall( Title, (
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Author ),
|
||||
xml_subterm( Book, Title )
|
||||
),
|
||||
Titles
|
||||
)
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q5: For each book found at both bn.com and amazon.com, list the title of the
|
||||
% book and its price from each source.
|
||||
|
||||
xml_query( q5, element('books-with-prices', [], BooksWithPrices) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Book, book ),
|
||||
element_name( Review, entry ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
input_document( 'reviews.xml', Reviews ),
|
||||
findall(
|
||||
element('book-with-prices', [], [
|
||||
Title,
|
||||
element('price-bn',[], BNPrice ),
|
||||
element('price-amazon',[], AmazonPrice )
|
||||
] ),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
xml_subterm( Reviews, Review ),
|
||||
xml_subterm( Review, Title ),
|
||||
xml_subterm( Book, element(price,_, BNPrice) ),
|
||||
xml_subterm( Review, element(price,_, AmazonPrice) )
|
||||
),
|
||||
BooksWithPrices
|
||||
).
|
||||
|
||||
% Q6: For each book that has at least one author, list the title and first two
|
||||
% authors, and an empty "et-al" element if the book has additional authors.
|
||||
|
||||
xml_query( q6, element(bib, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,FirstAuthor|Authors]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
findall( Author, xml_subterm(Book, Author), [FirstAuthor|Others] ),
|
||||
other_authors( Others, Authors )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q7: List the titles and years of all books published by Addison-Wesley after
|
||||
% 1991, in alphabetic order.
|
||||
|
||||
xml_query( q7, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Publisher, publisher ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
Title-element(book, [year=Year], [Title]),
|
||||
(
|
||||
xml_subterm( Bibliography, element(book, Attributes, Book) ),
|
||||
xml_subterm( Book, Publisher ),
|
||||
xml_subterm( Publisher, Text ),
|
||||
text_value( Text, "Addison-Wesley" ),
|
||||
member( year=Year, Attributes ),
|
||||
number_codes( YearNo, Year ),
|
||||
YearNo > 1991,
|
||||
xml_subterm( Book, Title )
|
||||
),
|
||||
TitleBooks
|
||||
),
|
||||
keysort( TitleBooks, TitleBookSet ),
|
||||
range( TitleBookSet, Books ).
|
||||
|
||||
% Q8: Find books in which the name of some element ends with the string "or" and
|
||||
% the same element contains the string "Suciu" somewhere in its content. For each
|
||||
% such book, return the title and the qualifying element.
|
||||
|
||||
xml_query( q8, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Book, book ),
|
||||
element_name( QualifyingElement, QualifyingName ),
|
||||
append( "Suciu", _Back, Suffix ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,QualifyingElement]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, QualifyingElement ),
|
||||
atom_codes( QualifyingName, QNChars ),
|
||||
append( _QNPrefix, "or", QNChars ),
|
||||
xml_subterm( QualifyingElement, TextItem ),
|
||||
text_value( TextItem, TextValue ),
|
||||
append( _Prefix, Suffix, TextValue ),
|
||||
xml_subterm( Book, Title )
|
||||
),
|
||||
Books
|
||||
).
|
||||
|
||||
% Q9: In the document "books.xml", find all section or chapter titles that
|
||||
% contain the word "XML", regardless of the level of nesting.
|
||||
|
||||
xml_query( q9, element(results, [], Titles) ) :-
|
||||
element_name( Title, title ),
|
||||
append( "XML", _Back, Suffix ),
|
||||
input_document( 'books.xml', Books ),
|
||||
findall(
|
||||
Title,
|
||||
(
|
||||
xml_subterm( Books, Title ),
|
||||
xml_subterm( Title, TextItem ),
|
||||
text_value( TextItem, TextValue ),
|
||||
append( _Prefix, Suffix, TextValue )
|
||||
),
|
||||
Titles
|
||||
).
|
||||
|
||||
% Q10: In the document "prices.xml", find the minimum price for each book, in the
|
||||
% form of a "minprice" element with the book title as its title attribute.
|
||||
|
||||
xml_query( q10, element(results, [], MinPrices) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Price, price ),
|
||||
input_document( 'prices.xml', Prices ),
|
||||
findall( Title, xml_subterm(Prices, Title), TitleBag ),
|
||||
sort( TitleBag, TitleSet ),
|
||||
element_name( Book, book ),
|
||||
findall(
|
||||
element(minprice, [title=TitleString], [MinPrice]),
|
||||
(
|
||||
member( Title, TitleSet ),
|
||||
xml_subterm( Title, TitleText ),
|
||||
text_value( TitleText, TitleString ),
|
||||
findall( PriceValue-Price, (
|
||||
xml_subterm( Prices, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
xml_subterm( Book, Price ),
|
||||
xml_subterm( Price, Text ),
|
||||
text_value( Text, PriceChars ),
|
||||
number_codes( PriceValue, PriceChars )
|
||||
),
|
||||
PriceValues
|
||||
),
|
||||
minimum( PriceValues, PriceValue-MinPrice )
|
||||
),
|
||||
MinPrices
|
||||
).
|
||||
|
||||
% Q11: For each book with an author, return the book with its title and authors.
|
||||
% For each book with an editor, return a reference with the book title and the
|
||||
% editor's affiliation.
|
||||
|
||||
xml_query( q11, element(bib, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
element_name( Editor, editor ),
|
||||
element_name( Affiliation, affiliation ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,FirstAuthor|Authors]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
findall( Author, xml_subterm(Book, Author), [FirstAuthor|Authors] )
|
||||
),
|
||||
Books
|
||||
),
|
||||
findall(
|
||||
element(reference, [], [Title,Affiliation]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book ),
|
||||
xml_subterm( Book, Title ),
|
||||
xml_subterm( Book, Editor ),
|
||||
xml_subterm( Editor, Affiliation )
|
||||
),
|
||||
References
|
||||
),
|
||||
append( Books, References, Results ).
|
||||
|
||||
% Q12: Find pairs of books that have different titles but the same set of authors
|
||||
% (possibly in a different order).
|
||||
|
||||
xml_query( q12, element(bib, [], Pairs) ) :-
|
||||
element_name( Author, author ),
|
||||
element_name( Book1, book ),
|
||||
element_name( Book2, book ),
|
||||
element_name( Title1, title ),
|
||||
element_name( Title2, title ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element('book-pair', [], [Title1,Title2]),
|
||||
(
|
||||
xml_subterm( Bibliography, Book1 ),
|
||||
findall( Author, xml_subterm(Book1, Author), AuthorBag1 ),
|
||||
sort( AuthorBag1, AuthorSet ),
|
||||
xml_subterm( Bibliography, Book2 ),
|
||||
Book2 @< Book1,
|
||||
findall( Author, xml_subterm(Book2, Author), AuthorBag2 ),
|
||||
sort( AuthorBag2, AuthorSet ),
|
||||
xml_subterm( Book1, Title1 ),
|
||||
xml_subterm( Book2, Title2 )
|
||||
),
|
||||
Pairs
|
||||
).
|
||||
|
||||
% Auxilliary Predicates
|
||||
|
||||
other_authors( [], [] ).
|
||||
other_authors( [Author|Authors], [Author|EtAl] ) :-
|
||||
et_al( Authors, EtAl ).
|
||||
|
||||
et_al( [], [] ).
|
||||
et_al( [_|_], [element('et-al',[],[])] ).
|
||||
|
||||
text_value( [pcdata(Text)], Text ).
|
||||
text_value( [cdata(Text)], Text ).
|
||||
|
||||
element_name( element(Name, _Attributes, _Content), Name ).
|
||||
|
||||
|
||||
/* range( +Pairs, ?Range ) when Pairs is a list of key-datum pairs and Range
|
||||
* is the list of data.
|
||||
*/
|
||||
range( [], [] ).
|
||||
range( [_Key-Datum|Pairs], [Datum|Data] ) :-
|
||||
range( Pairs, Data ).
|
||||
|
||||
/* minimum( +List, ?Min ) is true if Min is the least member of List in the
|
||||
* standard order.
|
||||
*/
|
||||
minimum( [H|T], Min ):-
|
||||
minimum1( T, H, Min ).
|
||||
|
||||
minimum1( [], Min, Min ).
|
||||
minimum1( [H|T], Min0, Min ) :-
|
||||
compare( Relation, H, Min0 ),
|
||||
minimum2( Relation, H, Min0, T, Min ).
|
||||
|
||||
minimum2( '=', Min0, Min0, T, Min ) :-
|
||||
minimum1( T, Min0, Min ).
|
||||
minimum2( '<', Min0, _Min1, T, Min ) :-
|
||||
minimum1( T, Min0, Min ).
|
||||
minimum2( '>', _Min0, Min1, T, Min ) :-
|
||||
minimum1( T, Min1, Min ).
|
||||
|
||||
/* input_document( +File, ?XML ) reads File and parses the input into the
|
||||
* "Document Value Model" XML.
|
||||
*/
|
||||
input_document( File, XML ) :-
|
||||
% Read InputFile as a list of chars
|
||||
see( File ),
|
||||
get_chars( Input ),
|
||||
seen,
|
||||
% Parse the Input chars into the term XML
|
||||
xml_parse( Input, XML ).
|
||||
|
||||
% Load the XML module.
|
||||
|
||||
:- use_module( library(xml) ).
|
||||
|
||||
|
||||
% Load a small library of utilities.
|
||||
|
||||
:- ensure_loaded( misc ).
|
||||
|
||||
|
Reference in New Issue
Block a user