view release on metacpan or search on metacpan
---------
- work with multiple DOM trees at once
- XPATH navigation (filesystem-like) navigation within a DOM tree
- copy/move nodes within a DOM tree or between two DOM trees
- node deletion
- node creation (element, attribute, text, cdata, comment,
well-balanced chunk)
- XPATH search and XML listing of nodes matched with XPATH
- XPATH-based conditional statements, while statement
- foreach statement allowing usage of relative XPATH expressions
- command output filtering with unix pipe, for example
xsh> list //word | grep [A-Z] | less
B<xsh(string,....)> - evaluates given string(s) as XSH2 commands.
B<call(name)> - call a given XSH2 subroutine.
B<count(string)> - evaluates given string as an XPath expression and returns either literal value of the result (in case of boolean, string and float result type) or number of nodes in a returned node-set.
B<literal(stringE<verbar>object)> - if passed a string, evaluates it as a XSH2 expression and returns the literal value of the result; if passed an object, returns literal value of the object. For example, B<literal('$docE<sol>expression')> returns t...
B<serialize(stringE<verbar>object)> - if passed a string, it first evaluates the string as a XSH2 expression to obtain a node-list object. Then it serializes the object into XML. The resulting string is equal to the output of the XSH2 command B<ls> a...
B<type(stringE<verbar>object)> - if passed a string, it first evaluates the string as XSH2 expression to obtain a node-list object. It returns a list of strings representing the types of nodes in the node-list (ordered in the canonical document order...
B<nodelist(stringE<verbar>object,...)> - converts its arguments to objects if necessary and returns a node-list consisting of the objects.
B<xpath(string, node?)> - evaluates a given string as an XPath expression in the context of a given node and returns the result.
B<echo(string,...)> - prints given strings on XSH2 output. Note, that in the interactive mode, XSH2 redirects all output to a specific terminal file handle stored in the variable B<$OUT>. So, if you for example mean to pipe the result to a shell comm...
In the following examples we use Perl to populate the Middle-Earth with Hobbits whose names are read from a text file called B<hobbits.txt>, unless there are some Hobbits in Middle-Earth already.
Example: Use Perl to read text files
xadd
=item Description:
Create new nodes of the B<node-type> given in the 1st argument of name specified in the 2nd argument and insert them to B<location>s relative to nodes in the node-list specified in the 4th argument.
For element nodes, the the 2nd argument B<expression> should evaluate to something like "E<lt>element-name att-name='attvalue' ...E<gt>". The B<E<lt>> and B<E<gt>> characters are optional. If no attributes are used, the expression may simply consist ...
Attribute nodes use the following syntax: "att-name='attvalue' [...]".
For the other types of nodes (text, cdata, comments) the expression should contain the node's literal content. Again, it is necessary to quote all whitespace and special characters as in any expression argument.
The B<location> argument should be one of: B<after>, B<before>, B<into>, B<replace>, B<append> or B<prepend>. See documentation of the B<location> argument type for more detail.
Optionally, for element and attribute nodes, a namespace may be specified with B<--namespace> or B<:n>. If used, the expression should evaluate to the desired namespace URI and the name of the element or attribute being inserted must have a prefix.
The command returns a node-list consisting of nodes it created.
Note, that instead of B<xinsert>, you can alternatively use one of B<xsh:new-attribute>, B<xsh:new-cdata>, B<xsh:new-chunk>, B<xsh:new-comment>, B<xsh:new-element>, B<xsh:new-element-ns>, B<xsh:new-pi>, and B<xsh:new-text> together with the command B...
Example: Give each chapter a provisional title element.
xsh> my $new_titles := xinsert element "<title font-size=large underline=yes>" \
into /book/chapter
xsh> xinsert text "Change me!" into $new_titles;
Example: Same as above, using xcopy and xsh:new-... instead of xinsert
xsh> my $new_titles := xcopy xsh:new-element("title","font-size","large","underline","yes") \
=item B<location>
One of: B<after>, B<before>, B<into>, B<append>, B<prepend>, B<replace>.
This argument is required by all commands that insert nodes to a document in some way to a destination described by an XPath expression. The meaning of the values listed above is supposed be obvious in most cases, however the exact semantics for loca...
B<afterE<sol>before> place the node right afterE<sol>before the destination node, except for when the destination node is a document node or one of the source nodes is an attribute: If the destination node is a document node, the source node is attac...
B<appendE<sol>prepend> appendsE<sol>prepends the source node to the destination node. If the destination node can contain other nodes (i.e. it is an element or a document node) then the entire source node is attached to it. In case of other destinati...
B<into> can also be used to place the source node to the end of an element (in the same way as B<append>), to attach an attribute to an element, or, if the destination node is a text node, cdata section, processing-instruction, attribute or comment, ...
B<replace> replaces the entire destination node with the source node except for the case when the destination node is an attribute and the source node is not. In such a case only the value of the destination attribute is replaced with the textual con...
=item B<node-type>
One of: element, attribute, text, cdata, comment, chunk and (EXPERIMENTALLY!) entity_reference. A chunk is a character string which forms a well-balanced piece of XML.
Example:
add element hobbit into //middle-earth/creatures;
add attribute 'name="Bilbo"' into //middle-earth/creatures/hobbit[last()];
add chunk '<hobbit name="Frodo">A small guy from <place>Shire</place>.</hobbit>'
into //middle-earth/creatures;
=item B<nodename>
should in XSH2 be written as either of
/foo/bar[ @baz = "bar" ]
avoiding any white-space outside the square brackets, or completely enclosed in brackets as in
( / foo / bar [ @baz = "bar" ] ).
XSH2 provides a number of powerful XPath extension functions, listed below and described in separate sections. XPath extension functions by default belong to XSH2 namespace B<http:E<sol>E<sol>xsh.sourceforge.netE<sol>xshE<sol>> with a namespace prefi...
XPath extension functions defined in XSH2: xsh:base-uri, xsh:context, xsh:current, xsh:doc, xsh:document, xsh:document-uri, xsh:documents, xsh:evaluate, xsh:filename, xsh:grep, xsh:id2, xsh:if, xsh:join, xsh:lc, xsh:lcfirst, xsh:lineno, xsh:lookup, x...
Example: Open a document and count all sections containing a subsection
xsh $scratch/> $v := open mydocument1.xml;
xsh $v/> $k := open mydocument2.xml;
xsh $k/> count //section[subsection]; # searches k
xsh $k/> count $v//section[subsection]; # searches v
=back
node-set xsh:new-attribute(string NAME1,string
VALUE1,[string NAME2, string VALUE2, ...])
=item Description:
Return a node-set consisting of newly created attribute nodes with given names and respective values.
=back
=head2 xsh:new-cdata
=over 4
=item Usage:
node-set xsh:new-cdata(string DATA)
=item Description:
Create a new cdata section node node filled with given B<DATA> and return a node-set containing the new node as its only member.
=back
=head2 xsh:new-chunk
=over 4
=item Usage:
node-set xsh:new-chunk(string XML)
lib/XML/XSH2/Completion.pm view on Meta::CPAN
our $NAMECHAR = '[-_.[:alnum:]]';
our $NNAMECHAR = '[-:_.[:alnum:]]';
our $NAME = "$NAMECHAR*$NNAMECHAR*[_.[:alpha:]]";
our $WILDCARD = '\*(?!\*|$NAME|\)|\]|\.)';
our $OPER = qr/(?:[,=<>\+\|]|-(?!$NAME)|(?:vid|dom|dna|ro)(?=\s*\]|\s*\)|\s*[0-9]+(?!$NNAMECHAR)|\s+{$NAMECHAR}|\s+\*))/;
# PATH-completion: system, !, exec, |,
our @nodetypes = qw(element attribute attributes text cdata pi comment chunk entity_reference);
sub complete_option {
my ($l)=@_;
if ($l=~/\s--encoding\s+$|\s:e\s+$/) {
}
if ($l=~/$M(\.|[a-zA-Z_][-a-zA-Z0-9_]*)$F\s+(:([[:alnum:]]?)|--([-_[:alnum:]]*))$/) {
my ($cmd,$o,$p)=($1,$2,$3||$4);
my $c = $XML::XSH2::Functions::COMMANDS{$cmd};
$c = $XML::XSH2::Functions::COMMANDS{$c} if (defined($c) and !ref($c));
if (defined($c) and defined($c->[3])) {
lib/XML/XSH2/Functions.pm view on Meta::CPAN
my $opts = shift;
init_XPATH_funcs($_xpc,shift);
return 1;
}
# ===================== XPATH EXT FUNC ================
sub get_XPATH_extensions {
qw( current doc filename grep id2 if join lc uc ucfirst lcfirst
lineno evaluate map matches match max min new-attribute
new-cdata new-chunk new-comment new-element new-element-ns new-pi
new-text node-type parse path reverse same serialize split sprintf
strmax strmin subst substr sum times var document documents lookup span context
resolve-uri base-uri document-uri
)
}
sub XPATH_doc {
die "Wrong number of arguments for function xsh:doc(nodeset)!\n" if (@_!=1);
my ($nodelist)=@_;
die "1st argument must be a nodeset in xsh:doc(nodeset)!\n"
lib/XML/XSH2/Functions.pm view on Meta::CPAN
if (@_!=1);
my $text=literal_value(shift);
my $doc = $_xpc->getContextNode;
unless (ref($doc) and ref($doc = $doc->ownerDocument())) {
die "No context document\n";
}
my $t=$doc->createComment($text);
return XML::LibXML::NodeList->new($t);
}
sub XPATH_new_cdata {
die "Wrong number of arguments for function xsh:new-cdata(string)!\n"
if (@_!=1);
my $name=literal_value(shift);
my $doc = $_xpc->getContextNode;
unless (ref($doc) and ref($doc = $doc->ownerDocument())) {
die "No context document\n";
}
my $t=$doc->createCDATASection($name);
return XML::LibXML::NodeList->new($t);
}
lib/XML/XSH2/Functions.pm view on Meta::CPAN
}
# return XPath identifying a node within its parent's subtree
sub node_address {
my $node = shift || $_xpc->getContextNode();
my $no_parent = shift;
my $name;
if ($_xml_module->is_element($node)) {
$name=cannon_name($node);
} elsif ($_xml_module->is_text($node) or
$_xml_module->is_cdata_section($node)) {
$name="text()";
} elsif ($_xml_module->is_comment($node)) {
$name="comment()";
} elsif ($_xml_module->is_pi($node)) {
$name="processing-instruction()";
} elsif ($_xml_module->is_attribute($node)) {
return "@".cannon_name($node);
}
if (!$no_parent and $node->parentNode) {
lib/XML/XSH2/Functions.pm view on Meta::CPAN
if ($_xml_module->is_document($node)) {
die "Error: Can't insert/copy/move document nodes!\n";
}
if (!defined($dest_doc)) {
$dest_doc = $_xml_module->owner_document($dest);
}
# destination: Attribute
if ($_xml_module->is_attribute($dest)) {
# source: Text, CDATA, Comment, Entity, Element
if ($_xml_module->is_text($node) ||
$_xml_module->is_cdata_section($node) ||
$_xml_module->is_comment($node) ||
$_xml_module->is_element($node) ||
$_xml_module->is_pi($node)) {
my $val = $_xml_module->is_element($node) ?
$node->textContent() : $node->getData();
if ($where eq 'replace' or $where eq 'into') {
$val=~s/^\s+|\s+$//g;
# xcopy will replace the value several times, which may not be intended
set_attr_ns($dest->ownerElement(),$dest->namespaceURI(),$dest->getName(),$val);
push @$rl,$dest->ownerElement()->getAttributeNodeNS($dest->namespaceURI(),$dest->getName()) if defined($rl);
lib/XML/XSH2/Functions.pm view on Meta::CPAN
_err("Warning: Ignoring incompatible nodes in insert/copy/move operation:\n",
ref($node)," $where ",ref($dest),"!");
return 1;
}
}
# destination: Document
elsif ($_xml_module->is_document($dest)) {
# source: Attribute, Text, CDATA
if ($_xml_module->is_attribute($node) or
$_xml_module->is_text($node) or
$_xml_module->is_cdata_section($node)
) {
_err("Warning: Ignoring incompatible nodes in insert/copy/move operation:\n",
ref($node)," $where ",ref($dest),"!");
return 1;
} elsif ($_xml_module->is_element($node)) {
# source: Element
my $copy=node_copy($node,$ns,$dest_doc,$dest);
my $destnode;
my $newwhere;
if ($where =~ /^(?:after|append|into)/) {
lib/XML/XSH2/Functions.pm view on Meta::CPAN
$dest->insertBefore($copy,$dest->firstChild());
} else {
$dest->appendChild($copy);
}
push @$rl,_expand_fragment($copy) if defined($rl);
}
}
}
# destination: Text, CDATA, Comment, PI
elsif ($_xml_module->is_text($dest) ||
$_xml_module->is_cdata_section($dest) ||
$_xml_module->is_comment($dest) ||
$_xml_module->is_pi($dest) ||
$_xml_module->is_entity_reference($dest)
) {
if ($where =~ /^(?:into|append|prepend)$/ and
($_xml_module->is_entity_reference($dest) ||
$_xml_module->is_entity_reference($node))) {
_err("Warning: Ignoring incompatible nodes in insert/copy/move operation:\n",
ref($node)," $where ",ref($dest),"!");
return 1;
lib/XML/XSH2/Functions.pm view on Meta::CPAN
}
return $el;
}
# create nodes from their textual representation
sub create_nodes {
my ($type,$str,$doc,$ns)=@_;
my @nodes=();
die "No document for create $type $str for.\n" unless ref($doc);
die "Can't create $type from empty specification.\n"
if ($str eq "" and $type !~ /text|cdata|comment/);
# return undef unless ($str ne "" and ref($doc));
if ($type eq 'chunk') {
@nodes=map {$_->childNodes()}
grep {ref($_)} ($_parser->parse_xml_chunk($str));
} else {
if ($type eq 'attribute') {
foreach (create_attributes($str)) {
my $at;
if ($_->[0]=~/^([^:]+):/ and $1 ne 'xmlns') {
$ns = get_registered_ns($1) if $ns eq "";
lib/XML/XSH2/Functions.pm view on Meta::CPAN
# __debug("ns: $ns\n".$el->toString());
} else {
print STDERR "invalid element $str\n" unless "$QUIET";
}
} elsif ($type eq 'text') {
push @nodes,$doc->createTextNode($str);
print STDERR "text=$str\n" if $DEBUG;
} elsif ($type eq 'entity_reference') {
push @nodes,$doc->createEntityReference($str);
print STDERR "entity_reference=$str\n" if $DEBUG;
} elsif ($type eq 'cdata') {
push @nodes,$doc->createCDATASection($str);
print STDERR "cdata=$str\n" if $DEBUG;
} elsif ($type eq 'pi') {
my ($name,$data)=($str=~/^\s*(?:\<\?)?(\S+)(?:\s+(.*?)(?:\?\>)?)?$/);
$data = "" unless defined $data;
my $pi = $doc->createPI($name,$data);
print STDERR "pi=<?$name ... $data?>\n" if $DEBUG;
push @nodes,$pi;
# print STDERR "cannot add PI yet\n" if $DEBUG;
} elsif ($type eq 'comment') {
push @nodes,$doc->createComment($str);
print STDERR "comment=$str\n" if $DEBUG;
lib/XML/XSH2/Functions.pm view on Meta::CPAN
$data=_ev_literal($exp)
} else {
my $pwd = pwd($node);
if ($fix) {
undef $fix;
} else {
if ($_xml_module->is_attribute($node)) {
$data=$node->value;
} elsif ($_xml_module->is_element($node) or
$_xml_module->is_document($node) or
$_xml_module->is_text_or_cdata($node) or
$_xml_module->is_comment($node) or
$_xml_module->is_pi($node)) {
$data=$_xml_module->toStringUTF8($node,$opts->{noindent} ? 0 :$INDENT);
} else {
die("Cannot edit ".ref($node)."\n");
}
}
$data="<!-- XSH-COMMENT: $pwd ".
($opts->{all} ? "($node_idx/$nodes) " : "")."-->\n"
.$data unless $opts->{'no-comment'};
lib/XML/XSH2/Functions.pm view on Meta::CPAN
return $text;
}
# strip whitespace from given nodes
sub strip_ws {
my ($opts,$exp)=@_;
my $ql=_ev_nodelist($exp);
foreach my $node (@$ql) {
if ($_xml_module->is_text($node)
or
$_xml_module->is_cdata_section($node)
or
$_xml_module->is_comment($node)
) {
my $data=_trim_ws($node->getData());
if ($data ne "") {
$data = "" unless defined $data;
$node->setData($data);
} else {
$node->unbindNode();
}
lib/XML/XSH2/Functions.pm view on Meta::CPAN
} elsif ($_xml_module->is_attribute($node)) {
$node->setValue(_trim_ws($node->getValue));
} elsif ($_xml_module->is_element($node) or
$_xml_module->is_document($node)) {
# traverse children, skip comments, strip text nodes
# until first element or PI or text node containing
# a non-ws character
my $child=$node->firstChild();
while ($child) {
if ($_xml_module->is_text($child) or
$_xml_module->is_cdata_section($child)) {
my $data=_trim_ws($child->getData());
if ($data ne "") {
$data = "" unless defined $data;
$child->setData($data);
last;
} else {
$child->unbindNode();
}
} elsif ($_xml_module->is_element($child) or
$_xml_module->is_pi($child)) {
last;
}
$child=$child->nextSibling();
}
# traverse children (upwards), skip comments, strip text nodes
# until first element or PI or text node containing a non-ws
# character
my $child=$node->lastChild();
while ($child) {
if ($_xml_module->is_text($child) or
$_xml_module->is_cdata_section($child)) {
my $data=_trim_ws($child->getData());
if ($data ne "") {
$data = "" unless defined $data;
$child->setData($data);
last;
} else {
$child->unbindNode();
}
} elsif ($_xml_module->is_element($child) or
$_xml_module->is_pi($child)) {
lib/XML/XSH2/Functions.pm view on Meta::CPAN
my ($code,$axis,$nodefilter,$filter)=@_;
$axis =~ s/::$//;
$axis=~s/-/_/g;
$filter =~ s/^\[\s*((?:.|\n)*?)\s*\]$/$1/ if defined $filter;
my $test;
if ($nodefilter eq "comment()") {
$test = q{ $_xml_module->is_comment($_[0]) }
} if ($nodefilter eq "text()") {
$test = q{ $_xml_module->is_text_or_cdata($_[0]) }
} elsif ($nodefilter =~ /processing-instruction\((\s*['"]([^'"]+)['"]\s*)?\)$/) {
$test = q{ $_xml_module->is_pi($_[0]) };
$test .= qq{ && (\$_[0]->nodeName eq '$1') } if $1 ne "";
} elsif ($nodefilter eq 'node()') {
$test = '1 ';
} elsif ($nodefilter =~ /^(?:([^:]+):)?(.+)$/) {
$test = q{ $_xml_module->is_element($_[0]) };
$test .= qq{ && (\$_[0]->getLocalName() eq '$2') } unless ($2 eq '*');
if ($1 ne "") {
my $ns = xsh_context_node()->lookupNamespaceURI($1);
lib/XML/XSH2/Functions.pm view on Meta::CPAN
sub node_type {
my ($node)=@_;
return undef unless $node;
if ($_xml_module->is_element($node)) {
return 'element';
} elsif ($_xml_module->is_attribute($node)) {
return 'attribute';
} elsif ($_xml_module->is_text($node)) {
return 'text';
} elsif ($_xml_module->is_cdata_section($node)) {
return 'cdata';
} elsif ($_xml_module->is_pi($node)) {
return 'pi';
} elsif ($_xml_module->is_entity_reference($node)) {
return 'entity_reference';
} elsif ($_xml_module->is_document($node)) {
return 'document';
} elsif ($_xml_module->is_document_fragment($node)) {
return 'chunk';
} elsif ($_xml_module->is_comment($node)) {
return 'comment';
lib/XML/XSH2/Grammar.pm view on Meta::CPAN
[$thisline,$thiscolumn,$thisoffset,$XML::XSH2::Functions::SCRIPT,'undefine',$item[3]];
}
param:
/[^=\s]+/ '=' exp
{ [$item[1],$item[3]] }
nodetype:
/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/
loc:
/after\s/
{ "after" }
| /before\s/
{ "before" }
| /(in)?to\s/
{ "into" }
lib/XML/XSH2/Help.pm view on Meta::CPAN
$variable, block, command, document, encoding, expression, filename,
location, node-type, nodename, perl-code, subroutine, xpath
XPath Extension Functions:
xsh:base-uri, xsh:context, xsh:current, xsh:doc, xsh:document,
xsh:document-uri, xsh:documents, xsh:evaluate, xsh:filename, xsh:grep,
xsh:id2, xsh:if, xsh:join, xsh:lc, xsh:lcfirst, xsh:lineno, xsh:lookup,
xsh:map, xsh:match, xsh:matches, xsh:max, xsh:min, xsh:new-attribute,
xsh:new-cdata, xsh:new-chunk, xsh:new-comment, xsh:new-element,
xsh:new-element-ns, xsh:new-pi, xsh:new-text, xsh:parse, xsh:path,
xsh:resolve-uri, xsh:reverse, xsh:same, xsh:serialize, xsh:span,
xsh:split, xsh:sprintf, xsh:strmax, xsh:strmin, xsh:subst, xsh:substr,
xsh:sum, xsh:times, xsh:uc, xsh:ucfirst, xsh:var
END
$HELP{'command'}=[<<'END'];
command
lib/XML/XSH2/Help.pm view on Meta::CPAN
to 'xsh'. A program may however call the [xpath-extensions]
command to map XSH2 XPath extension functions into the default
namespace, so that they may be used directly without any
prefix.
XPath extension functions defined in XSH2: xsh:base-uri,
xsh:context, xsh:current, xsh:doc, xsh:document,
xsh:document-uri, xsh:documents, xsh:evaluate, xsh:filename,
xsh:grep, xsh:id2, xsh:if, xsh:join, xsh:lc, xsh:lcfirst,
xsh:lineno, xsh:lookup, xsh:map, xsh:match, xsh:matches,
xsh:max, xsh:min, xsh:new-attribute, xsh:new-cdata,
xsh:new-chunk, xsh:new-comment, xsh:new-element,
xsh:new-element-ns, xsh:new-pi, xsh:new-text, xsh:parse,
xsh:path, xsh:resolve-uri, xsh:reverse, xsh:same,
xsh:serialize, xsh:span, xsh:split, xsh:sprintf, xsh:strmax,
xsh:strmin, xsh:subst, xsh:substr, xsh:sum, xsh:times, xsh:uc,
xsh:ucfirst, xsh:var
Example: Open a document and count all sections containing a subsection
xsh $scratch/> $v := open mydocument1.xml;
lib/XML/XSH2/Help.pm view on Meta::CPAN
For element nodes, the the 2nd argument [expression] should
evaluate to something like "<element-name att-name='attvalue'
...>". The '<' and '>' characters are optional. If no
attributes are used, the expression may simply consist the
element name. Note, that in the first case, the quotes are
required since the expression contains spaces.
Attribute nodes use the following syntax: "att-name='attvalue'
[...]".
For the other types of nodes (text, cdata, comments) the
expression should contain the node's literal content. Again,
it is necessary to quote all whitespace and special characters
as in any expression argument.
The [location] argument should be one of: 'after', 'before',
'into', 'replace', 'append' or 'prepend'. See documentation of
the [location] argument type for more detail.
Optionally, for element and attribute nodes, a namespace may
be specified with '--namespace' or ':n'. If used, the
expression should evaluate to the desired namespace URI and
the name of the element or attribute being inserted must have
a prefix.
The command returns a node-list consisting of nodes it
created.
Note, that instead of 'xinsert', you can alternatively use one
of [xsh:new-attribute], [xsh:new-cdata], [xsh:new-chunk],
[xsh:new-comment], [xsh:new-element], [xsh:new-element-ns],
[xsh:new-pi], and [xsh:new-text] together with the command
[xcopy].
Example: Give each chapter a provisional title element.
xsh> my $new_titles := xinsert element "<title font-size=large underline=yes>" \
into /book/chapter
xsh> xinsert text "Change me!" into $new_titles;
lib/XML/XSH2/Help.pm view on Meta::CPAN
see also: insert move xmove
END
$HELP{'xadd'}=$HELP{'xinsert'};
$HELP{'node-type'}=[<<'END'];
Node-type argument type
description:
One of: element, attribute, text, cdata, comment, chunk and
(EXPERIMENTALLY!) entity_reference. A chunk is a character
string which forms a well-balanced piece of XML.
Example:
add element hobbit into //middle-earth/creatures;
add attribute 'name="Bilbo"' into //middle-earth/creatures/hobbit[last()];
add chunk '<hobbit name="Frodo">A small guy from <place>Shire</place>.</hobbit>'
into //middle-earth/creatures;
END
lib/XML/XSH2/Help.pm view on Meta::CPAN
'append/prepend' appends/prepends the source node to the
destination node. If the destination node can contain other
nodes (i.e. it is an element or a document node) then the
entire source node is attached to it. In case of other
destination node types, the textual content of the source node
is appended/prepended to the content of the destination node.
'into' can also be used to place the source node to the end of
an element (in the same way as 'append'), to attach an
attribute to an element, or, if the destination node is a text
node, cdata section, processing-instruction, attribute or
comment, to replace its textual content with the textual
content of the source node.
'replace' replaces the entire destination node with the source
node except for the case when the destination node is an
attribute and the source node is not. In such a case only the
value of the destination attribute is replaced with the
textual content of the source node. Note also that document
node can never be replaced.
lib/XML/XSH2/Help.pm view on Meta::CPAN
usage: node-set xsh:new-pi(string NAME, [string DATA])
description:
Create a new processing instruction node node with given
'NAME' and (optionally) given 'DATA' and return a node-set
containing the new node as its only member.
END
$HELP{'xsh:new-cdata'}=[<<'END'];
usage: node-set xsh:new-cdata(string DATA)
description:
Create a new cdata section node node filled with given 'DATA'
and return a node-set containing the new node as its only
member.
END
$HELP{'xsh:new-chunk'}=[<<'END'];
usage: node-set xsh:new-chunk(string XML)
description:
lib/XML/XSH2/Help.pm view on Meta::CPAN
'serialize(string|object)' - if passed a string, it first evaluates the
string as a XSH2 expression to obtain a node-list object. Then it
serializes the object into XML. The resulting string is equal to the
output of the XSH2 command [ls] applied on the same expression or
object expression only without indentation and folding.
'type(string|object)' - if passed a string, it first evaluates the
string as XSH2 expression to obtain a node-list object. It returns a
list of strings representing the types of nodes in the node-list
(ordered in the canonical document order). The returned type strings
are: 'element', 'attribute', 'text', 'cdata', 'pi', 'entity_reference',
'document', 'chunk', 'comment', 'namespace', 'unknown'.
'nodelist(string|object,...)' - converts its arguments to objects if
necessary and returns a node-list consisting of the objects.
'xpath(string, node?)' - evaluates a given string as an XPath
expression in the context of a given node and returns the result.
'echo(string,...)' - prints given strings on XSH2 output. Note, that in
the interactive mode, XSH2 redirects all output to a specific terminal
lib/XML/XSH2/Help.pm view on Meta::CPAN
'xsh:map' => undef,
'xsh:new-element-ns' => undef,
'xsh:sum' => undef,
'process-xinclude' => 'load and insert XInclude sections',
'do' => 'execute a given block of commands',
'xinsert' => 'create nodes on all target locations',
'xsh:documents' => undef,
'register-xsh-namespace' => 'register a prefix for the XSH2 namespace',
'apropos' => 'search the documentation',
'verbose' => 'make XSH2 print many messages',
'xsh:new-cdata' => undef,
'xsh:parse' => undef,
'filename' => 'specifying filenames',
'unregister-namespace' => 'unregister namespace prefix',
'throw' => 'throw an exception',
'xsh:new-text' => undef,
'nobackups' => 'turn off backup file creation',
'parser-expands-entities' => 'turn on/off parser\'s tendency to expand entities',
'set-enc' => 'set document\'s charset (encoding)',
'while' => 'simple while loop',
'try' => 'try/catch statement',
lib/XML/XSH2/LibXMLCompat.pm view on Meta::CPAN
sub is_attribute {
my ($class,$node)=@_;
return $node->nodeType == XML::LibXML::XML_ATTRIBUTE_NODE();
}
sub is_text {
my ($class,$node)=@_;
return $node->nodeType == XML::LibXML::XML_TEXT_NODE();
}
sub is_text_or_cdata {
my ($class,$node)=@_;
return $node->nodeType == XML::LibXML::XML_TEXT_NODE() || $node->nodeType == XML::LibXML::XML_CDATA_SECTION_NODE();
}
sub is_cdata_section {
my ($class,$node)=@_;
return $node->nodeType == XML::LibXML::XML_CDATA_SECTION_NODE();
}
sub is_pi {
my ($class,$node)=@_;
return $node->nodeType == XML::LibXML::XML_PI_NODE();
}
lib/XML/XSH2/Parser.pm view on Meta::CPAN
my @item = ();
my %item = ();
my $repeating = $_[2];
my $_noactions = $_[3];
my @arg = defined $_[4] ? @{ &{$_[4]} } : ();
my $_itempos = $_[5];
my %arg = ($#arg & 01) ? @arg : (@arg, undef);
my $text;
my $lastsep;
my $current_match;
my $expectation = new XML::XSH2::Parser::_Runtime::Expectation(q{/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/});
$expectation->at($_[1]);
my $thisoffset;
tie $thisoffset, q{XML::XSH2::Parser::_Runtime::OffsetCounter}, \$text, $thisparser;
my $thiscolumn;
tie $thiscolumn, q{XML::XSH2::Parser::_Runtime::ColCounter}, \$text, $thisparser;
my $thisline;
tie $thisline, q{XML::XSH2::Parser::_Runtime::LineCounter}, \$text, $thisparser;
while (!$_matched && !$commit)
{
XML::XSH2::Parser::_Runtime::_trace(q{Trying production: [/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/]},
XML::XSH2::Parser::_Runtime::_tracefirst($_[1]),
q{nodetype},
$tracelevel)
if defined $::RD_TRACE;
my $thisprod = $thisrule->{"prods"}[0];
$text = $_[1];
my $_savetext;
@item = (q{nodetype});
%item = (__RULE__ => q{nodetype});
my $repcount = 0;
XML::XSH2::Parser::_Runtime::_trace(q{Trying terminal: [/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/]}, XML::XSH2::Parser::_Runtime::_tracefirst($text),
q{nodetype},
$tracelevel)
if defined $::RD_TRACE;
undef $lastsep;
$expectation->is(q{})->at($text);
unless ($text =~ s/\A($skip)/$lastsep=$1 and ""/e and $text =~ m/\A(?:element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference)/)
{
$text = $lastsep . $text if defined $lastsep;
$expectation->failed();
XML::XSH2::Parser::_Runtime::_trace(q{<<Didn't match terminal>>},
XML::XSH2::Parser::_Runtime::_tracefirst($text))
if defined $::RD_TRACE;
last;
}
$current_match = substr($text, $-[0], $+[0] - $-[0]);
substr($text,0,length($current_match),q{});
XML::XSH2::Parser::_Runtime::_trace(q{>>Matched terminal<< (return value: [}
. $current_match . q{])},
XML::XSH2::Parser::_Runtime::_tracefirst($text))
if defined $::RD_TRACE;
push @item, $item{__PATTERN1__}=$current_match;
XML::XSH2::Parser::_Runtime::_trace(q{>>Matched production: [/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/]<<},
XML::XSH2::Parser::_Runtime::_tracefirst($text),
q{nodetype},
$tracelevel)
if defined $::RD_TRACE;
$_matched = 1;
last;
}
lib/XML/XSH2/Parser.pm view on Meta::CPAN
'line' => 402,
'name' => 'nodetype',
'opcount' => 0,
'prods' => [
bless( {
'actcount' => 0,
'dircount' => 0,
'error' => undef,
'items' => [
bless( {
'description' => '/element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference/',
'hashname' => '__PATTERN1__',
'ldelim' => '/',
'line' => 403,
'lookahead' => 0,
'mod' => '',
'pattern' => 'element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference',
'rdelim' => '/'
}, 'XML::XSH2::Parser::_Runtime::Token' )
],
'line' => undef,
'number' => 0,
'patcount' => 1,
'strcount' => 0,
'uncommit' => undef
}, 'XML::XSH2::Parser::_Runtime::Production' )
],
src/xsh_grammar.xml view on Meta::CPAN
<literal>type(string|object)</literal> -
if passed a string, it first evaluates
the string as &XSH; expression to obtain a node-list object.
It returns a list of strings representing
the types of nodes in the node-list
(ordered in the canonical document order).
The returned type strings are:
<literal>element</literal>,
<literal>attribute</literal>,
<literal>text</literal>,
<literal>cdata</literal>,
<literal>pi</literal>,
<literal>entity_reference</literal>,
<literal>document</literal>,
<literal>chunk</literal>,
<literal>comment</literal>,
<literal>namespace</literal>,
<literal>unknown</literal>.
</para>
<para>
<literal>nodelist(string|object,...)</literal> -
src/xsh_grammar.xml view on Meta::CPAN
characters are optional. If no attributes are used, the
expression may simply consist the element name. Note,
that in the first case, the quotes are required since
the expression contains spaces.
</para>
<para>
Attribute nodes use the following syntax:
"att-name='attvalue' [...]".
</para>
<para>
For the other types of nodes (text, cdata, comments) the
expression should contain the node's literal content. Again,
it is necessary to quote all whitespace and special
characters as in any expression argument.
</para>
<para>
The <xref linkend="loc"/> argument should be one of:
<literal>after</literal>, <literal>before</literal>,
<literal>into</literal>,
<literal>replace</literal>, <literal>append</literal>
or <literal>prepend</literal>. See documentation
src/xsh_grammar.xml view on Meta::CPAN
the expression should evaluate to the desired namespace
URI and the name of the element or attribute being inserted
<emphasis>must have a prefix</emphasis>.
</para>
<para>
The command returns a node-list consisting of nodes it created.
</para>
<para>
Note, that instead of <literal>xinsert</literal>, you can alternatively use
one of <xref linkend="new_attribute_function"/>,
<xref linkend="new_cdata_function"/>,
<xref linkend="new_chunk_function"/>,
<xref linkend="new_comment_function"/>,
<xref linkend="new_element_function"/>,
<xref linkend="new_element_ns_function"/>,
<xref linkend="new_pi_function"/>, and
<xref linkend="new_text_function"/>
together with the command <xref linkend="xcopy_command"/>.
</para>
<example>
<title>Give each chapter a provisional title element.</title>
src/xsh_grammar.xml view on Meta::CPAN
</description>
<see-also>
<ruleref ref="insert_command" arguments=""/>
<ruleref ref="move_command" arguments=""/>
<ruleref ref="xmove_command" arguments=""/>
</see-also>
</documentation>
</rule>
<rule id="nodetype" name="node-type" type="argtype" inline="no">
<production>
<regexp>element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference</regexp>
</production>
<documentation sections="Argtypes Manipulation">
<title>Node-type argument type</title>
<shortdesc>node type specification (such as element, attribute, etc.)</shortdesc>
<description>
<para>
One of: element, attribute, text, cdata, comment, chunk
and (EXPERIMENTALLY!) entity_reference. A
chunk is a character string which forms a well-balanced
piece of XML.
</para>
<example>
<code>add element hobbit into //middle-earth/creatures;
add attribute 'name="Bilbo"' into //middle-earth/creatures/hobbit[last()];
add chunk '<hobbit name="Frodo">A small guy from <place>Shire</place>.</hobbit>'
<tab count="1"/>into //middle-earth/creatures;
</code>
src/xsh_grammar.xml view on Meta::CPAN
document node) then the entire source node is attached to
it. In case of other destination node types, the textual
content of the source node is appended/prepended to the
content of the destination node.
</para>
<para>
<literal>into</literal> can also be used to place
the source node to the end of an element (in the same way
as <literal>append</literal>), to attach an attribute
to an element, or, if the destination node is a text node,
cdata section, processing-instruction, attribute or comment,
to replace its textual content with the textual content of
the source node.
</para>
<para>
<literal>replace</literal> replaces the entire destination
node with the source node except for the case when the
destination node is an attribute and the source node is
not. In such a case only the value of the destination
attribute is replaced with the textual content of the
source node. Note also that document node can never be
src/xsh_grammar.xml view on Meta::CPAN
<description>
<para>
Create a new processing instruction node node with given
<literal>NAME</literal> and (optionally) given
<literal>DATA</literal> and return a node-set containing
the new node as its only member.
</para>
</description>
</documentation>
</rule>
<rule id="new_cdata_function" type="function" name="xsh:new-cdata" inline="no">
<documentation>
<usage>node-set xsh:new-cdata(string DATA)</usage>
<description>
<para>
Create a new cdata section node node filled with
given <literal>DATA</literal> and return a node-set
containing the new node as its only member.
</para>
</description>
</documentation>
</rule>
<rule id="new_chunk_function" type="function" name="xsh:new-chunk" inline="no">
<documentation>
<usage>node-set xsh:new-chunk(string XML)</usage>
<description>
t/08more_functions.t view on Meta::CPAN
call x_assert 'new-element("foo","bar","baz","bag","dag")/self::foo[@bar="baz" and @bag="dag"]';
call x_assert 'new-element-ns("f:foo","gee","bar","baz","bag","dag")/self::*[name()="f:foo" and local-name()="foo" and namespace-uri()="gee" and @bar="baz" and @bag="dag"]';
call x_assert 'new-text("some text")/self::text()="some text"';
call x_assert 'new-comment("some text")/self::comment()="some text"';
call x_assert 'new-pi("name","value")/self::processing-instruction()[name()="name"]="value"';
call x_assert 'new-cdata("some text")/self::text()="some text"';
call x_assert 'serialize(new-cdata("some text"))="<![CDATA[some text]]>"';
EOF
plan tests => 4+@xsh_test;
}
END { ok(0) unless $loaded; }
use XML::XSH2 qw/&xsh &xsh_init &set_quiet &xsh_set_output/;
$loaded=1;
ok(1);