pax_global_header 0000666 0000000 0000000 00000000064 14261055676 0014526 g ustar 00root root 0000000 0000000 52 comment=fe5be8d08fbede6066e6aaff1c43ea14105af836
xmls/ 0000775 0000000 0000000 00000000000 14261055676 0012055 5 ustar 00root root 0000000 0000000 xmls/.github/ 0000775 0000000 0000000 00000000000 14261055676 0013415 5 ustar 00root root 0000000 0000000 xmls/.github/workflows/ 0000775 0000000 0000000 00000000000 14261055676 0015452 5 ustar 00root root 0000000 0000000 xmls/.github/workflows/main.yml 0000664 0000000 0000000 00000004261 14261055676 0017124 0 ustar 00root root 0000000 0000000 name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
test:
# The type of runner that the job will run on
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ubuntu-latest]
lisp:
- ccl
- sbcl
# - allegro Allegro from Roswell can't load FiveAM from quicklisp
- ecl
- cmu
# - clisp clisp install from Roswell does not work.
# - mkcl Tests not implemented on mkcl
# - abcl ABCL install from Roswell does not work
steps:
- uses: actions/checkout@v2
- name: Checkout submodules
shell: bash
run: |
git submodule update --init --recursive
# Lisp setup copied from here: https://github.com/3b/ci-example/blob/master/.github/workflows/CI.yml
- name: cache .roswell
id: cache-dot-roswell
uses: actions/cache@v1
with:
path: ~/.roswell
key: ${{ runner.os }}-dot-roswell-${{ matrix.lisp }}-${{ hashFiles('**/*.asd') }}
restore-keys: |
${{ runner.os }}-dot-roswell-${{ matrix.lisp }}-
${{ runner.os }}-dot-roswell-
- name: install roswell
shell: bash
# always run install, since it does some global installs and setup that isn't cached
env:
LISP: ${{ matrix.lisp }}
# Use a previous release of Roswell to avoid error encountered
# due to libcurl3 not being available.
# Source of fix: https://github.com/avodonosov/drakma/commit/fbba29181ba2962f5031da581bd2de4dac98733d
run: |
sudo apt-get install -y libcurl4
curl -L https://raw.githubusercontent.com/roswell/roswell/a8fd8a3c33078d6f06e6cda9d099dcba6fbefcb7/scripts/install-for-ci.sh | sh
# Compile first in a separate step to make the test output more readable
- name: tests
shell: bash
run: |
ros -S `pwd`/:: -l run-tests.lisp
xmls/.gitignore 0000664 0000000 0000000 00000000013 14261055676 0014037 0 ustar 00root root 0000000 0000000
.DS_Store
xmls/COPYING 0000664 0000000 0000000 00000003013 14261055676 0013105 0 ustar 00root root 0000000 0000000 Copyright (c) 2003, Miles Egan; Copyright (c) 2004-2015 Robert P. Goldman, Mike
Boldt, and SIFT, LLC
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
xmls/Changelog 0000664 0000000 0000000 00000003670 14261055676 0013675 0 ustar 00root root 0000000 0000000 # $Id$
3.2
* Add XMLS/octets to handle character encodings. Many thanks to
Daniel Eliason for contributing this.
3.1
* Fix namespacing issue (Github #5) on attributes. Thanks to David
A. Thompson.
1.8
* Added optional error suppression when items aren't found.
1.7.1
* Fixed a bug that caused breakage on Lispworks.
1.7
* Added write-prologue and write-prolog.
1.6
1.5
* Added helpers to parse string and integer content in an element.
* Now testable with clisp.
* Fix unicode bug loading with SBCL.
1.4.1
* Fixed bugs in parsing CDATA that could cause crashes in the parser.#
1.4
* Thanks to Norman Werner, fixed bug in handling of multi-byte characters.
1.3
* Bumped the version to record the presence of the helper functions.
1.2.1, 1.2.2
* Miscellaneous bugfixes, not recorded by anyone.
1.2
* add compilation guard around *whitespace* (5 million people)
* generate-xml serializes numbers and symbols automatically (Robert Goldman)
1.1.1
* fix typo in test function guard
1.1
* merge Barry Wilkes patches for ws in attributes
* merge Barry Wilkes lispworks compatibility patches
* merge Gary King's MCL compatibilty patches
* merge Clayton Wheeler's memory optimizations
* merge Robert Goldman's Allegro fixes
1.0
* Parse/emit unprintables as entities.
* Parse numeric xml entitites thanks to Damien Diederen.
* Optionally indent write-xml output.
* Fix namespace resolution bug
0.5
* Fix compress-whitespace handling.
* Add Damien Diederen's entity-handling patch.
0.4
* Made substantial changes to get xmls working in cmucl and clisp.
* Reduced consing again somewhat.
0.3
* Bugfix from Andrew Philpot.
* Consing reduced by about 40%.
0.2
* Now skips DTDs.
* Roughly seven times faster.
* Parses CDATA sections.
* Only uses one token of lookahead.
* Handles content at the end of the document.
0.1
* First release.
xmls/Makefile 0000664 0000000 0000000 00000002756 14261055676 0013527 0 ustar 00root root 0000000 0000000 system := xmls
webhome_dir := /project/${system}/public_html/
webhome_private := common-lisp.net:${webhome_dir}
webhome_public := "http://common-lisp.net/project/${system}/"
sourceDirectory := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
webfiles := web-page/clnet-page.shtml web-page/styles.css README.html
ifeq (${user},)
userat :=
else
userat := ${user}@
endif
website:=${userat}common-lisp.net:/project/${system}/public_html/
version := $(shell cat "version.lisp-expr")
XMLSDIR := "${system}-$(version)"
TARBALL := "build/${XMLSDIR}.tar.gz"
.PHONY: archive publish-archive website publish-latest
archive: ;
mkdir -p build
git archive --output ${TARBALL} --prefix 'xmls/' HEAD
gpg -o ${TARBALL}.asc --sign ${TARBALL}
md5sum --binary ${TARBALL} > ${TARBALL}.md5
# must be done after archive
publish-archive:
$(eval GPGSIG := ${TARBALL}.asc)
$(eval MD5SUM := ${TARBALL}.md5)
rsync --times --chmod=a+rX,ug+w ${TARBALL} ${GPGSIG} ${MD5SUM} ${website}
ssh common-lisp.net "cd ${webhome_dir}; ln -sf ${TARBALL} latest.tar.gz; ln -sf ${GPGSIG} latest.tar.gz.asc; ln -sf ${MD5SUM} latest.tar.gz.md5;"
# must be done after archive
publish-latest:
rsync --times --recursive --chmod=a+rX,ug+w build/${XMLSDIR} ${website}
ssh common-lisp.net "cd ${webhome_dir}; ln -sf ${XMLSDIR} latest;"
website: ;
rsync -lt --no-g ${webfiles} ${website}
ssh common-lisp.net "cd ${webhome_dir}; cp clnet-page.shtml index.shtml;"
publish: archive publish-archive publish-latest website
clean:
rm -r build
xmls/README.html 0000664 0000000 0000000 00000025657 14261055676 0013717 0 ustar 00root root 0000000 0000000
XMLS: Common Lisp XML Parser
XMLS
Manual For Version 3
Summary
Xmls is a small, simple, non-validating xml parser for Common Lisp. It's
designed to be a self-contained, easily embedded parser that recognizes a useful
subset of the XML spec. It provides a simple mapping from xml to lisp
structures or s-expressions and back.
Since XMLS was first released it has gained some additional
complications/features. In particular:
Now XMLS by default parses XML documents into lisp structures,
rather than s-expressions. This makes accessing the structures
simpler and more reliable. See section on backward compatibility.
We have added clearly named accessors to further improve
extraction of information from parsed XML.
Thanks to Max Rottenkolber, we now have the affiliated library,
xmls/octets that will open streams for the XMLS parser,
processing any content-type declarations in the process.
Features
Free (BSD license).
Understands enough of the xml spec to parse many common documents, including
those occurring in common internet protocols like xml-rpc, webdav, and BEEP.
Parses 85 out of the 98 valid documents in the oasis parser compliance suite.
Small and easily embedded. The entire parser is contained in one
file and it's currently less than 600 lines of code. Xmls is written in
pure lisp and requires no external parsing tools or foreign libraries.
Supports xml namespaces.
Threadsafe.
Serializes s-expr list structures back to xml as well as parsing xml.
Limitations
Parses entire document into memory and consequently can't handle large
documents.
No detailed error reporting.
Hand-built LR parser, meaning the parser structure is a little hard
to understand, and can be hard to modify. Use of CL-YACC or similar
might be a preferable route for a rewrite.
XML Representation
Parsed xml is represented as a nested lisp structure, unlike in the
original version, where it was a lisp list. The s-expression
representation is still maintained, and there are functions to
translate to and from this notation.
XML representation as lisp structures
In the structure representation, a node, corresponding to an XML
element, is defined as follows:
(defstruct (node (:constructor %make-node))
name
ns
attrs
children)
Xmls also includes a helper function, make-node for creating xml nodes
of this form:
(make-node &key name ns attrs children)
Xmls provides the corresponding accessor functions node-name, node-ns
node-attrs, and node-children.
XML representation as s-expressions
In the s-expression representation, a node is represented as follows:
(name (attributes) children*)
A name is either a simple string, if the element does not belong to a namespace,
or a list of (name namespace-url) if the element does belong to a namespace.
Attributes are stored as (name value) lists.
Children are stored as a list of either element nodes or text nodes.
For example, the following xml document:
<?xml version="1.0"?>
<!-- test document -->
<book title='The Cyberiad'>
<!-- comment in here -->
<author xmlns='http://authors'>Stanislaw Lem</author>
<info:subject xmlns:info='http://bookinfo' rank='1'>"Cybernetic Fables"</info:subject>
</book>
Parse accepts either a string or an input stream and attempts to parse the xml
document contained therein. It will return the s-expr parse tree if it's
successful or nil if parsing fails.
If COMPRESS-WHITESPACE is non-NIL, content nodes will be trimmed of whitespace and
empty whitespace strings between nodes will be discarded.
(parse-to-list source (&rest args))
Functions as PARSE, but returns a list representation
of the XML document, instead of a structure.
(write-prologue xml-decl doctype stream)
write-prologue writes the leading
<?xml ... ?> and <!DOCTYPE ... >
elements to stream.
xml-decl is an alist of attribute name value pairs.
Valid xml-decl attributes per the xml spec are "version", "encoding",
and "standalone", though write-prologue does not verify this.
doctype is a string containing the document type definition.
(write-prolog xml-decl doctype stream)
U.S. spelling alternative to write-prologue.
(write-xml xml stream &key (indent nil))
write-xml accepts a lisp list in the format described above and writes the
equivalent xml string to stream. Currently, if nodes use namespaces xmls will not
assign namespaces prefixes but will explicitly assign the namespace to each node. This
will be changed in a later release.
Xmls will indent the generated xml output if indent is non-nil.
(toxml node &key (indent nil))
TOXML is a convenience wrapper around write-xml that returns the in a newly
allocated string.
XMLS provides two exported functions to translate between the CL
structure representation of the XML tree and the s-expression
representation:
node->nodelist
Translate the structure representation into s-expressions.
nodelist->nodes
Translate the s-expression representation of an XMLS parse tree
into lisp structures.
Helper functions
These are intended to allow programmers to avoid direct manipulation of the
XMLS element representation. If you use these, your code should be easier to
read and you will avoid problems if there is a change in internal
representation (such changes would be hard to even find, much less correct, if
using the lists directly).
make-xmlrep (tag &key attribs children)
Constructor function.
xmlrep-add-child! (xmlrep child)
Add a new child node to the XMLREP node.
xmlrep-tag (xmlrep)
Extract the tag from XMLREP.
xmlrep-tagmatch (tag treenode)
Returns true if TAG is the tag of TREENODE. Match is
case insensitive (quite possibly this is the Wrong Thing).
xmlrep-attribs (xmlrep)
Extract the attributes from an XMLREP node.
xmlrep-children (xmlrep)
Extract the children from an XMLREP node.
xmlrep-find-child-tags (tag treenode)
Return all of the (direct) children of TREENODE whose tags are TAG.
Matching done by xmlrep-tagmatch.
Returns the single string-valued child of TREENODE.
If there is more than one child, or if a single child is not
a simple value, returns IF-UNFOUND, which defaults to :ERROR.
xmlrep-integer-child (treenode)
Find the single child of TREENODE whose value is a string that
can be parsed into an integer. Returns an
error if there is more than one child, or if a single child is not
appropriately valued.
Find the value of ATTRIB, a string, in TREENODE.
The value should be either "true" or "false". The
function will return T or NIL, accordingly. If there is no ATTRIB,
will return the value of IF-UNDEFINED, which defaults to :ERROR.
XMLS itself simply processes strings or streams. This means that it
does not provide native support for handling character encodings, as
declared in the XML headers. The system xmls/octets,
which depends on xmls provides that support with the
exported function make-xml-stream, which takes an
octet-stream as argument, processes its header, choosing the
appropriate character encoding, and then returns a stream suitable for
passing to xmls:parse.
Probably make-xml-stream should be made generic, and support
arguments of other types (e.g., strings interpreted as filenames,
pathnames, etc.).
Installation
xmls can be installed as an asdf system. An asdf
system definition is provided with the distribution.
Previous versions of XMLS were single files, and could be installed simply by
loading the file xmls.lisp. This option is no longer supported.
Contact Information
Please contact Robert Goldman, rpgoldman AT sift.net with any
questions or bug reports.
## Summary
Xmls is a small, simple, non-validating xml parser for Common Lisp. It's designed to be a self-contained, easily embedded parser that recognizes a useful subset of the XML spec. It provides a simple mapping from xml to lisp structures or s-expressions and back.
Since XMLS was first released it has gained some additional complications/features. In particular:
* **Now XMLS by default parses XML documents into lisp structures, rather than s-expressions.** This makes accessing the structures simpler and more reliable. See [section on backward compatibility](#Compatibility).
* We have added clearly named accessors to further improve extraction of information from parsed XML.
* Thanks to Max Rottenkolber, we now have the affiliated library, [`xmls/octets`](#octets) that will open streams for the XMLS parser, processing any content-type declarations in the process.
## Features
* Free (BSD license).
* Understands enough of the xml spec to parse many common documents, including those occurring in common internet protocols like xml-rpc, webdav, and BEEP. Parses 85 out of the 98 valid documents in the oasis parser compliance suite.
* Small and easily embedded. The entire parser is contained in one file and it's currently less than 600 lines of code. Xmls is written in pure lisp and requires no external parsing tools or foreign libraries.
* Supports xml namespaces.
* Threadsafe.
* Serializes s-expr list structures back to xml as well as parsing xml.
## Limitations
* Parses entire document into memory and consequently can't handle large documents.
* No detailed error reporting.
* Hand-built LR parser, meaning the parser structure is a little hard to understand, and can be hard to modify. Use of CL-YACC or similar might be a preferable route for a rewrite.
## XML Representation
Parsed xml is represented as a nested lisp structure, unlike in the original version, where it was a lisp list. The s-expression representation is still maintained, and there are [functions to translate to and from this notation](#translators).
### XML representation as lisp structures
In the structure representation, a node, corresponding to an XML element, is defined as follows:
(defstruct (node (:constructor %make-node))
name
ns
attrs
children)
XMLS also includes a helper function, `make-node` for creating xml nodes of this form:
(make-node &key name ns attrs children)
Xmls provides the corresponding accessor functions node-name, node-ns node-attrs, and node-children.
### XML representation as s-expressions
In the s-expression representation, a node is represented as follows:
(name (attributes) children*)
A name is either a simple string, if the element does not belong to a namespace, or a list of (name namespace-url) if the element does belong to a namespace.
Attributes are stored as `(name value)` lists, with optional properties after the value for `(name value . plist)`. At present, the only property used is `:attr-ns`, the namespace on the attribute, if any. If there is no namespace, the attribute may not be present.
Children are stored as a list of either element nodes or text nodes.
For example, the following xml document:
```
Stanislaw Lem"Cybernetic Fables"
```
Would parse as:
```
("book" (("title" "The Cyberiad"))
(("author" . "http://authors") NIL "Stanislaw Lem")
(("subject" . "http://bookinfo") (("rank" "1")) "\"Cybernetic Fables\""))
```
### Backward Compatibility
To detect whether in this version of XMLS the return value of `PARSE` will be a list or a structure, check for the feature `:XMLS-NODES-ARE-STRUCTS`.
For old code that wants XML parsed into lists, instead of structures, you may replace calls to `(parse str)` with `(node->nodelist (parse str))`.
For greater convenience, we offer `PARSE-TO-LIST`, which performs the same function.
## Usage
The interface is straightforward. The two main functions are `PARSE` and `TOXML`.
Parse accepts either a string or an input stream (`source`) and attempts to parse the XML document contained therein. It will return the parse tree as a structure if it's successful or `nil` if parsing fails.
If `COMPRESS-WHITESPACE` is non-`NIL`, content nodes will be trimmed of whitespace and empty whitespace strings between nodes will be discarded.
(parse-to-list source (&rest args))
Functions as `PARSE`, but returns a list representation of the XML document, instead of a structure.
(write-prologue xml-decl doctype stream)
`write-prologue` writes the leading `` and `` elements to `stream`. `xml-decl` is an alist of attribute name, value pairs. Valid xml-decl attributes per the xml spec are "version", "encoding", and "standalone", though `write-prologue` does not verify this. `doctype` is a string containing the document type definition.
(write-prolog xml-decl doctype stream)
U.S. spelling alternative to `write-prologue`.
(write-xml xml stream &key (indent nil))
`write-xml` accepts a lisp list in the format described above and writes the equivalent xml string to stream. Currently, if nodes use namespaces XMLS will not assign namespaces prefixes but will explicitly assign the namespace to each node. This will be changed in a later release. XMLS will indent the generated xml output if `indent` is non-nil.
(toxml node &key (indent nil))
`TOXML` is a convenience wrapper around `write-xml` that returns the in a newly allocated string.
### Translating to and from s-expressions
XMLS provides two exported functions to translate between the CL structure representation of the XML tree and the s-expression representation:
node->nodelist (node)
Translate the structure representation into s-expressions.
nodelist->nodes (xmls-sexp)
Translate the s-expression representation of an XMLS parse tree into lisp structures.
### Helper functions
These are intended to allow programmers to avoid direct manipulation of the XMLS element representation. If you use these, your code should be easier to read and you will avoid problems if there is a change in internal representation (such changes would be hard to even find, much less correct, if using the lists directly).
make-xmlrep (tag &key attribschildren)
Constructor function.
xmlrep-add-child! (xmlrepchild)
Add a new child node to the XMLREP node.
xmlrep-tag (xmlrep)
Extract the tag from XMLREP.
xmlrep-tagmatch (tagtreenode)
Returns true if TAG is the tag of TREENODE. Match is case _insensitive_ (quite possibly this is the Wrong Thing).
xmlrep-attribs (xmlrep)
Extract the attributes from an XMLREP node.
xmlrep-children (xmlrep)
Extract the children from an XMLREP node.
xmlrep-find-child-tags (tagtreenode)
Return all of the (direct) children of treenode whose tags are tag. Matching done by [`xmlrep-tagmatch`](#xmlrep-tagmatch).
Returns the _single_ string-valued child of treenode. If there is more than one child, or if a single child is not a simple value, returns if-unfound, which defaults to :ERROR.
xmlrep-integer-child (treenode)
Find the _single_ child of treenode whose value is a string that can be parsed into an integer. Returns an error if there is more than one child, or if a single child is not appropriately valued.
Find the value of attrib, a string, in treenode. The value should be either "true" or "false". The function will return T or NIL, accordingly. If there is no attrib, will return the value of if-undefined, which defaults to :ERROR.
## XMLS/Octets
XMLS itself simply processes strings or streams. This means that it does not provide native support for handling character encodings, as declared in the XML headers. The system `xmls/octets`, which depends on `xmls` provides that support with the exported function `make-xml-stream`, which takes an octet-stream as argument, processes its header, choosing the appropriate character encoding, and then returns a stream suitable for passing to `xmls:parse`.
Probably `make-xml-stream` should be made generic, and support arguments of other types (e.g., strings interpreted as filenames, pathnames, etc.).
## Installation
XMLS can be installed as an ASDF system. An ASDF system definition is provided with the distribution.
Previous versions of XMLS were single files, and could be installed simply by loading the file xmls.lisp. This option is no longer supported.
## Contact Information
Please post issues in the [GitHub Repository](https://github.com/rpgoldman/xmls/issues)
xmls/extract-path.lisp 0000664 0000000 0000000 00000013412 14261055676 0015353 0 ustar 00root root 0000000 0000000 ;; (declaim (optimize (speed 0) (space 0) (debug 3) (safety 3) (compilation-speed 0)))
(in-package :xmls)
;; XML extraction tool
(defun extract-path ( key-list xml )
"Extracts data from XML parse tree. KEY-LIST is a path for descending down
named objects in the XML parse tree. For each KEY-LIST element, XML subforms
are searched for a matching tag name. Finally the whole last XML subform on the
path is normally returned if found; however the symbol * may be added at the end
of KEY-LIST to return list of all objects /enclosed/ by the last subform on
KEY-LIST. Also KEY-LIST may be dotted as explained below to return XML tag
attributes from the last subform on KEY-LIST.
XML is to have the forms as returned by PARSE-TO-LIST or PARSE:
(tag-name (attributes-list) subform*),
((tag-name . name-space) (attributes-list) subform*), or
#s(node :name tag-name
:ns name-space
:attrs attributes-list
:children subform*)
The first element in KEY-LIST must match the top level form in XML.
Subsequently each element in the KEY-LIST is to match a subform.
An element of KEY-LIST may be a string atom. In that case the first subform
with tag-name matching the string is matched. An element of KEY-LIST may also
be a list of string atoms in this format:
(tag-name (attribute-name attribute-value) ...)
The first subform with name matching TAG-NAME /and/ having attributes matching
attribute-names and attribute-values is matched. Zero or more attribute/value
pairs may be given.
Normally the whole subform matching last element in KEY-LIST is returned. The
symbol * can be the last element of KEY-LIST to return list of all subforms
enclosed by the last matched form. Attributes of last matched subform may be
searched by ending KEY-LIST in dot notation, in which case the string after dot
matches an attribute name. The two element list of attribute name and value is
returned. The symbol * may be used after dot to return the whole attribute list.
In the case where the search fails NIL is returned. However it is possible that
the search partially succeeds down the key path. Three values are returned
altogether and the 2nd and 3rd values give information about how much of
KEY-LIST was matched, and at what point in XML:
(values RESULT KEY-LIST-FRAGMENT XML-FRAGMENT)
When RESULT is non-NIL, the others are NIL. When result is NIL however, the
others are:
XML-FRAGMENT
The last XML form that /did/ match in the key list. It matches the first
element of KEY-LIST-FRAGMENT.
KEY-LIST-FRAGMENT
The /remaining/ part of the KEY-LIST that did not succeed. However the
/first/ item on KEY-LIST-FRAGMENT matches the XML-FRAGMENT returned. The
failure is at the second item on KEY-LIST-FRAGMENT.
In the case of complete failure, where even the very first item on KEY-LIST does not
match the top XML form given, all three return values are NIL. (It suffices to check
the first two return values.)"
(labels ((attribs-match-p ( key-attribs-list xml-attribs-list )
;; search for (attr-name attr-value) pairs from KEY-ATTRIBS-LIST on
;; XML-ATTRIBS-LIST. true if all key pairs found.
(loop
:with attribs-match-var := t
:for attrib-key-pair :in key-attribs-list
:do
(setq attribs-match-var
(and attribs-match-var
(find attrib-key-pair xml-attribs-list :test #'equal)))
:finally (return attribs-match-var)))
(find-test ( key xml-form )
;; test whether the XML-FORM matches KEY
(cond
;; just the XML tag name in key
;; XML name is simple string
((and (stringp key)
(stringp (xmlrep-tag xml-form)))
(string-equal key (xmlrep-tag xml-form)))
;; key form (tag-name (attr-name attr-value) ...)
((and (find-test (car key) xml-form)
(attribs-match-p (cdr key) (xmlrep-attribs xml-form))))))
(descend ( key-list xml-form )
;; recursive run down KEY-LIST. If XML-FORM runs down to NIL before reaching
;; the end of KEY-LIST, it will be NIL at the end. If not, what is
;; remaining of XML-FORM is the found item.
(cond
;; KEY-LIST ends without dotted item, at the target XML form
((null (cdr key-list))
(values xml-form nil nil))
;; dotted item at the end of KEY-LIST, search attribute list of target XML form
((atom (cdr key-list))
(if (eq '* (cdr key-list))
(values (xmlrep-attribs xml-form) nil nil)
(find (cdr key-list) (xmlrep-attribs xml-form)
:test (lambda (key item) (equal key (car item))))))
;; more tag names to match on KEY-LIST
('t
(if (eq '* (cadr key-list))
(values (xmlrep-children xml-form) nil nil)
(let ((selected-xml-form (find (cadr key-list) (xmlrep-children xml-form)
:test #'find-test)))
(if selected-xml-form
(descend (cdr key-list) selected-xml-form)
;; no matching sub-form, indicate what part of KEY-LIST did not match
(values nil key-list xml-form))))))))
;; empty list, degenerate usage
(when (null key-list)
(error "KEY-LIST is empty."))
;; search down after initial match
(if (find-test (car key-list) xml)
(descend key-list xml)
(values nil nil nil))))
xmls/fiveam-tests.lisp 0000664 0000000 0000000 00000017657 14261055676 0015375 0 ustar 00root root 0000000 0000000 ;; (declaim (optimize (speed 0) (space 0) (debug 3) (safety 3) (compilation-speed 0)))
(in-package :common-lisp-user)
(defpackage xmls-test
(:use :common-lisp :fiveam :xmls)
)
(in-package :xmls-test)
(def-suite xmls-test)
(in-suite xmls-test)
(test check-cdata-backtrack
(is (equalp (make-node :name "name" :children (list "x]"))
(parse ""))))
(test bigger-check-cdata-backtrack
(is (equalp (make-node :name "description"
:children
(list
"Link to Catalog In this sequel to 2010's surprise hit, Greg Heffley, the kid who made \"wimpy\" cool is back in an all-new family comedy based on the best-selling follow-up novel by Jeff Kinney. (Kinney's Wimpy Kid\" series has thus far sold 42 million books.) As he begins seventh grade, Greg and his older brother [...]"))
(parse ""))))
(test simple-nodelist-translator
(is (equalp (nodelist->node (list "description" nil
"Link to Catalog In this sequel to 2010's surprise hit, Greg Heffley, the kid who made \"wimpy\" cool is back in an all-new family comedy based on the best-selling follow-up novel by Jeff Kinney. (Kinney's Wimpy Kid\" series has thus far sold 42 million books.) As he begins seventh grade, Greg and his older brother [...]"))
(parse ""))))
(def-fixture parsed-greeting ()
(let ((node
(with-open-file (str (asdf:system-relative-pathname "xmls" "tests/beep/greeting1.xml")
:direction :input)
(parse str))))
(&body)))
(test check-accessors
(with-fixture parsed-greeting ()
(is (equal "greeting" (node-name node)))
(is (= 3 (length (node-children node))))
(is (null (node-attrs node)))
(is (equal (list "profile" "profile" "profile")
(mapcar #'node-name (node-children node))))))
(test check-xmlrep-accessors
(with-fixture parsed-greeting ()
(is (equal "greeting" (xmlrep-tag node)))
(is (= 3 (length (xmlrep-children node))))
(is (null (xmlrep-attribs node)))
(is (equal (list "profile" "profile" "profile")
(mapcar #'xmlrep-tag (xmlrep-children node))))))
(test attribute-with-prefixed-name
(is (string= "style"
(getf (xmls::find-attrib "name"
(xmls:parse " "))
:attr-ns))))
(def-fixture article-parsed-as-list ()
(let ((parse-tree
(with-open-file (str (asdf:system-relative-pathname "xmls" "tests/nxml/genetics-article.xml")
:direction :input)
(xmls:parse-to-list str))))
(&body)))
(test check-extract-path-from-list-nodes
(with-fixture article-parsed-as-list ()
;; retrieve first of items matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" "ref")
parse-tree)))
(is (= 4 (length result)))
(is (equalp (nth 0 result)
'("ref" . "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle")))
(is (equalp (nth 1 result)
'(("id" "gkt903-B1")))))
;; retrieve tag attributes of first item matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" "ref" . *)
parse-tree)))
(is (equalp result
'(("id" "gkt903-B1")))))
;; retrieve all items enclosed by element matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" *)
parse-tree)))
(is (= 41 (length result)))
(is (equalp (nth 0 result)
'(("title" . "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle") nil "REFERENCES")))
(is (equalp (nth 1 (nth 1 result))
'(("id" "gkt903-B1"))))
(is (equalp (nth 1 (nth 15 result))
'(("id" "gkt903-B15")))))
;; select specific item among several with same tag based on tag attributes
;; here selecting on "ref" in the path...
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" ("ref" ("id" "gkt903-B15")) "element-citation"
"article-title")
parse-tree)))
(is (equalp result
'(("article-title" . "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle") NIL
"HNS, a nuclearcytoplasmic shuttling sequence in HuR"))))))
(def-fixture article-parsed-as-struct ()
(let ((parse-tree
(with-open-file (str (asdf:system-relative-pathname "xmls" "tests/nxml/genetics-article.xml")
:direction :input)
(xmls:parse str))))
(&body)))
(test check-extract-path-from-struct-nodes
(with-fixture article-parsed-as-struct ()
;; retrieve first of items matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" "ref")
parse-tree)))
(is (string= (node-name result) "ref"))
(is (string= (node-ns result) "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle"))
(is (equalp (node-attrs result) '(("id" "gkt903-B1")))))
;; retrieve tag attributes of first item matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" "ref" . *)
parse-tree)))
(is (equalp result '(("id" "gkt903-B1")))))
;; retrieve all items enclosed by element matching the path
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" *)
parse-tree)))
(is (= 41 (length result)))
(is (equalp (nth 0 result)
(make-node :name "title"
:ns "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle"
:attrs nil
:children '("REFERENCES"))))
(is (equalp (node-attrs (nth 1 result))
'(("id" "gkt903-B1"))))
(is (equalp (node-attrs (nth 15 result))
'(("id" "gkt903-B15")))))
;; select specific item among several with same tag based on tag attributes
;; here selecting on "ref" in the path...
(let ((result (xmls:extract-path '("OAI-PMH" "GetRecord" "record" "metadata" "article"
"back" "ref-list" ("ref" ("id" "gkt903-B15")) "element-citation"
"article-title")
parse-tree)))
(is (equalp result
(make-node :name "article-title"
:ns "http://dtd.nlm.nih.gov/2.0/xsd/archivearticle"
:attrs NIL
:children '("HNS, a nuclearcytoplasmic shuttling sequence in HuR")))))))
xmls/octets-tests/ 0000775 0000000 0000000 00000000000 14261055676 0014516 5 ustar 00root root 0000000 0000000 xmls/octets-tests/flux/ 0000775 0000000 0000000 00000000000 14261055676 0015474 5 ustar 00root root 0000000 0000000 xmls/octets-tests/flux/flux-test-iso-8859-1.xml 0000664 0000000 0000000 00000011277 14261055676 0021522 0 ustar 00root root 0000000 0000000
Les derniers documents du CERTA.
http://www.certa.ssi.gouv.fr
CERTA (Centre d'Expertise gouvernemental de Reponse et de Traitement des Attaques informatiques).frCERTA-2011-AVI-110 : Vulnérabilité dans IBM WepSphere Portal (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-110/CERTA-2011-AVI-110.htmlUne vulnérabilité a été corrigée dans IBM WebSphere Portal et permet à un utilisateur malintentionné de porter atteinte à la confidentialité des données.CERTA-2011-AVI-109 : Multiples vulnérabilités dans Cisco ASA série 5500 (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-109/CERTA-2011-AVI-109.htmlQuatre vulnérabilités ont été corrigées dans les appareils Cisco ASA série 5500. Trois d'entre elles permettent de réaliser un déni de service à distance, et la quatrième permet d'accéder à des données confidentielles sur le système de fichiers.CERTA-2011-AVI-108 : Vulnérabilité dans Microsoft Malware Protection Engine (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-108/CERTA-2011-AVI-108.htmlUne vulnérabilité dans Microsoft Malware Protection Engine permet à une personne malintentionnée d'élever ses privilèges.CERTA-2011-AVI-107 : Vulnérabilité dans Novell Netware (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-107/CERTA-2011-AVI-107.htmlUne vulnérabilité dans Novell Netware permet à une personne distante malintentionnée d'exécuter du code arbitraire.CERTA-2011-AVI-106 : Vulnérabilité dans CA HIPS (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-106/CERTA-2011-AVI-106.htmlUne vulnérabilité dans CA HIPS permet l'exécution de code arbitraire à distance.CERTA-2011-AVI-105 : Multiples vulnérabilités dans les logiciels Cisco TelePresence (24 février
2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-105/CERTA-2011-AVI-105.htmlDe multiples vulnérabilités touchent la ligne de produits Cisco TelePresence, elles permettent notamment d'exécuter du code arbitraire ou de provoquer un déni de service à distance.CERTA-2011-AVI-104 : Vulnérabilité dans Cisco Firewall Services Module (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-104/CERTA-2011-AVI-104.htmlUne vulnérabilité permettant d'effectuer un déni de service à distance a été identifiée dans le produit Cisco Firewall Services Module (FWSM).CERTA-2011-AVI-079 : Vulnérabilité dans plusieurs implémentations de Java (24 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-079/CERTA-2011-AVI-079.htmlUne vulnérabilité affecte plusieurs implémentations de Java, elle permet un déni de service à distance.CERTA-2011-AVI-103 : Vulnérabilité dans ISC Bind (23 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-103/CERTA-2011-AVI-103.htmlUne vulnérabilité dans le serveur DNS ISC Bind permet à un utilisateur malintentionné de provoquer un déni de service à distance.CERTA-2011-AVI-102 : Vulnérabilités dans RedHat Directory Server (23 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-102/CERTA-2011-AVI-102.htmlPlusieurs vulnérabilités dans l'annuaire RedHat Directory Server permettent à un utilisateur malveillant de provoquer un déni de service à distance ou d'élever ses privilèges.CERTA-2011-AVI-101 : Multiples vulnérabilités dans Ruby (22 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-101/CERTA-2011-AVI-101.htmlDeux vulnérabilités dans Ruby ont été corrigées. La première permet de contourner la politique de sécurité et la seconde de porter atteinte à l'intégrité des données.CERTA-2011-AVI-100 : Vulnérabilités dans Mailman (22 février 2011)http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-100/CERTA-2011-AVI-100.htmlDeux vulnérabilités présentes dans Mailman permettent à un utilisateur distant de conduire des attaques de type injection de code indirecte.
xmls/octets-tests/flux/flux-test-utf-16be.xml 0000664 0000000 0000000 00000022446 14261055676 0021510 0 ustar 00root root 0000000 0000000 þÿ <