XML/Input: Difference between revisions

From Rosetta Code
< XML
Content added Content deleted
(added Haskell)
m (Fixed lang tags.)
Line 22: Line 22:


=={{header|ActionScript}}==
=={{header|ActionScript}}==
<lang actionscript>
<lang actionscript>package
package
{
{
import flash.display.Sprite;
import flash.display.Sprite;
Line 44: Line 43:
}
}
}
}
}</lang>
}
</lang>
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
simply using regular expressions
simply using regular expressions
Line 67: Line 65:
names .= name1 . "`n"
names .= name1 . "`n"


msgbox % names </lang>
msgbox % names</lang>
=={{header|AWK}}==
=={{header|AWK}}==
The following code extracts the value of the property "Name" from every Student tag. It does not handle the <tt>&amp;#CODE;</tt>; this can be left to others: a way to cope with it fastly, is to output a very simple HTML structure, so that the interpretation is left to an HTML reader/browser.
The following code extracts the value of the property "Name" from every Student tag. It does not handle the <tt>&amp;#CODE;</tt>; this can be left to others: a way to cope with it fastly, is to output a very simple HTML structure, so that the interpretation is left to an HTML reader/browser.
Line 130: Line 128:


{{works with|gawk}} or {{works with|nawk}}
{{works with|gawk}} or {{works with|nawk}}
<lang sh>awk -f getXML.awk sample.xml | awk '
<lang awk>awk -f getXML.awk sample.xml | awk '
$1 == "TAG" {tag = $2}
$1 == "TAG" {tag = $2}
tag == "Student" && /Name=/ {print substr($0, index($0, "=") + 1)}
tag == "Student" && /Name=/ {print substr($0, index($0, "=") + 1)}
Line 137: Line 135:


{{works with|gawk}}
{{works with|gawk}}
<lang sh>gawk -f xmlparser.awk sample.xml | awk '
<lang awk>gawk -f xmlparser.awk sample.xml | awk '
$1 == "begin" {tag = $2}
$1 == "begin" {tag = $2}
$1 == "attrib" {attrib = $2}
$1 == "attrib" {attrib = $2}
Line 217: Line 215:
{{libheader|Qt}}
{{libheader|Qt}}


<lang c++>
<lang cpp>/*
/*
Using the Qt library's XML parser.
Using the Qt library's XML parser.
*/
*/
Line 247: Line 244:
}
}
return 0;
return 0;
}</lang>
}
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 272: Line 268:
(push (dom:get-attribute child "Name") student-names))))</lang>
(push (dom:get-attribute child "Name") student-names))))</lang>


produces <lang lisp>("April" "Bob" "Chad" "Dave" "Émily")</lang>
produces<lang lisp>("April" "Bob" "Chad" "Dave" "Émily")</lang>


=={{header|D}}==
=={{header|D}}==
{{libheader|KXML}}
{{libheader|KXML}}
<lang d>
<lang d>import kxml.xml;
import kxml.xml;
char[]xmlinput =
char[]xmlinput =
"<Students>
"<Students>
Line 300: Line 295:
break;
break;
}
}
}</lang>
}
</lang>


=={{header|Haskell}}==
=={{header|Haskell}}==
Line 330: Line 324:
J's system includes several XML processing libraries. This task is probably best addressed using XPath (this is the type of problem XPath was designed to solve), but the task description implicitly discourages that method. So we can use the SAX library instead:
J's system includes several XML processing libraries. This task is probably best addressed using XPath (this is the type of problem XPath was designed to solve), but the task description implicitly discourages that method. So we can use the SAX library instead:


<lang j> load'xml/sax'
<lang j>load'xml/sax'
saxclass 'Students'
saxclass 'Students'
startElement =: ([: smoutput 'Name' getAttribute~ [)^:('Student'-:])
startElement =: ([: smoutput 'Name' getAttribute~ [)^:('Student'-:])
cocurrent'base'
cocurrent'base'
process_Students_ XML</lang>
process_Students_ XML</lang>
April
April
Bob
Bob
Line 487: Line 481:
=={{header|R}}==
=={{header|R}}==
{{libheader|XML}}
{{libheader|XML}}
<lang R>
<lang R>library(XML)
library(XML)
#Read in XML string
#Read in XML string
str <- readLines(tc <- textConnection('<Students>
str <- readLines(tc <- textConnection('<Students>
Line 500: Line 493:
</Students>'))
</Students>'))
close(tc)
close(tc)
str
str</lang>
</lang>
[1] "<Students>"
[1] "<Students>"
[2] " <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />"
[2] " <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />"
Line 511: Line 503:
[8] " <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"&#x00C9;mily\" />"
[8] " <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"&#x00C9;mily\" />"
[9] "</Students>"
[9] "</Students>"
<lang R>
<lang R>#Convert to an XML tree
#Convert to an XML tree
xmltree <- xmlTreeParse(str)
xmltree <- xmlTreeParse(str)


Line 529: Line 520:
#Change the encoding so that Emily displays correctly
#Change the encoding so that Emily displays correctly
Encoding(studentsnames) <- "UTF-8"
Encoding(studentsnames) <- "UTF-8"
studentsnames
studentsnames</lang>
</lang>
[1] "April" "Bob" "Chad" "Dave" "Émily"
[1] "April" "Bob" "Chad" "Dave" "Émily"


Line 554: Line 544:
Scala has native XML support, with query constructs similar to XPath and XQuery.
Scala has native XML support, with query constructs similar to XPath and XQuery.


<lang scala>
<lang scala>object xmlstudents extends Application {
object xmlstudents extends Application {


val students =
val students =
Line 569: Line 558:


students \ "Student" \\ "@Name" foreach println
students \ "Student" \\ "@Name" foreach println
}</lang>
}
</lang>


=={{header|Slate}}==
=={{header|Slate}}==
Line 576: Line 564:
Slate's XML Reader is still being developed at the time of this writing.
Slate's XML Reader is still being developed at the time of this writing.
<lang slate>
<lang slate>slate[1]> [ |tree|
slate[1]> [ |tree|


tree: (Xml SimpleParser newOn: '<Students>
tree: (Xml SimpleParser newOn: '<Students>
Line 597: Line 584:
Dave
Dave
&#x00C9;mily
&#x00C9;mily
Nil
Nil</lang>

</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==
Line 609: Line 594:
foreach node $studentNodes {
foreach node $studentNodes {
puts [$node getAttribute Name]
puts [$node getAttribute Name]
}</lang>
}
</lang>
Using {{libheader|TclXML}}
Using {{libheader|TclXML}}
<lang tcl>package require xml
<lang tcl>package require xml
Line 672: Line 656:
}
}
}
}
}</lang>
}

</lang>


=={{header|Vedit macro language}}==
=={{header|Vedit macro language}}==
This implementation finds all ''Student'' tags and then displays the contents of their ''Name'' parameter.
This implementation finds all ''Student'' tags and then displays the contents of their ''Name'' parameter.
<lang vedit>
<lang vedit>Repeat(ALL) {
Repeat(ALL) {
Search("<Student|X", ERRBREAK)
Search("<Student|X", ERRBREAK)
#1 = Cur_Pos
#1 = Cur_Pos
Line 688: Line 669:
Type_Block(#2, Cur_Pos)
Type_Block(#2, Cur_Pos)
Type_Newline
Type_Newline
}</lang>
}
</lang>


Output:
Output:
Line 711: Line 691:
For Each name In names
For Each name In names
Console.WriteLine(name)
Console.WriteLine(name)
Next
Next</lang>
</lang>

Revision as of 18:53, 22 November 2009

Task
XML/Input
You are encouraged to solve this task according to the task description, using any language you may know.

Given the below XML fragment, extract the list of student names using whatever means desired. If the only viable method is to use XPath, refer the reader to the task XML and XPath.

<lang xml><Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />

</Students></lang>

Expected Output

April
Bob
Chad
Dave
Émily

ActionScript

<lang actionscript>package {

   import flash.display.Sprite;
   public class XMLReading extends Sprite
   {
       public function XMLReading()
       {
           var xml:XML = <Students>
                           <Student Name="April" />
                           <Student Name="Bob" />
                           <Student Name="Chad" />
                           <Student Name="Dave" />
                           <Student Name="Emily" />
                         </Students>;
           for each(var node:XML in xml..Student)
           {
               trace(node.@Name);
           }
       }
   }

}</lang>

AutoHotkey

simply using regular expressions <lang AutoHotkey>students = ( <Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />

</Students> )

quote = " ; " pos = 1 while, pos := RegExMatch(students, "Name=.(\w+)" . quote . "\sGender" , name, pos + 1) names .= name1 . "`n"

msgbox % names</lang>

AWK

The following code extracts the value of the property "Name" from every Student tag. It does not handle the &#CODE;; this can be left to others: a way to cope with it fastly, is to output a very simple HTML structure, so that the interpretation is left to an HTML reader/browser.

<lang awk>function parse_buf() {

   if ( match(buffer, /<Student[ \t]+[^>]*Name[ \t]*=[ \t]*"([^"]*)"/, mt) != 0 ) {
     students[mt[1]] = 1
   }
   buffer = ""

}

BEGIN {

 FS=""
 mode = 0
 buffer = ""
 li = 1

}

mode==1 {

 for(i=1; i <= NF; i++) {
   buffer = buffer $i
   if ( $i == ">" ) {
     mode = 0;
     break;
   }
 }
 if ( mode == 0 ) {
   li = i
 } else {
   li = 1
 }
 # let us process the buffer if "complete"
 if ( mode == 0 ) {
   parse_buf()
 }

}

mode==0 {

 for(i=li; i <= NF; i++) {
   if ( $i == "<" ) {
     mode = 1
     break;
   }
 }
 for(j=i; i <= NF; i++) {
   buffer = buffer $i
   if ( $i == ">" ) {
     mode = 0
     parse_buf()
   }
 }
 li = 1

}

END {

 for(k in students) {
   print k
 }

}</lang> Using getXML.awk written by Jan Weber, one could do this:

Works with: gawk

or

Works with: nawk

<lang awk>awk -f getXML.awk sample.xml | awk '

   $1 == "TAG"                 {tag = $2}
   tag == "Student" && /Name=/ {print substr($0, index($0, "=") + 1)}

'</lang> Using xmlparser.awk by Steve Coile, one can do this:

Works with: gawk

<lang awk>gawk -f xmlparser.awk sample.xml | awk '

   $1 == "begin"                                         {tag = $2}
   $1 == "attrib"                                        {attrib = $2}
   $1 == "value" && tag == "STUDENT" && attrib == "name" {print $2}

'</lang>

Both of these produce this output

April
Bob
Chad
Dave
&#x00C9;mily
Works with: XMLgawk

Scripts in AWK are often one-liners. This one-liner implementation searches for Student tags and then displays the contents of their Name attribute. The following line is meant to be typed in on the command line of a Unix shell or an MS-DOS command window.

gawk -lxml 'XMLSTARTELEM == "Student" {print XMLATTR["Name"]}' rosetta.xml

Output:

April
Bob
Chad
Dave
Émily

C

Library: LibXML

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  3. include <libxml/parser.h>
  4. include <libxml/tree.h>

static void print_names(xmlNode *node) {

 xmlNode *cur_node = NULL;
 for (cur_node = node; cur_node; cur_node = cur_node->next) {
   if (cur_node->type == XML_ELEMENT_NODE) {
     if ( strcmp(cur_node->name, "Student") == 0 ) {

xmlAttr *prop = NULL; if ( (prop = xmlHasProp(cur_node, "Name")) != NULL ) { printf("%s\n", prop->children->content);

}

     }
   }
   print_names(cur_node->children);
 }

}

const char *buffer =

 "<Students>\n"
 "  <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />\n"
 "  <Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />\n"
 "  <Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />\n"
 "  <Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">\n"
 "    <Pet Type=\"dog\" Name=\"Rover\" />\n"
 "  </Student>\n"
 "  <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />\n"
 "</Students>\n";

int main() {

 xmlDoc *doc = NULL;
 xmlNode *root = NULL;
 doc = xmlReadMemory(buffer, strlen(buffer), NULL, NULL, 0);
 if ( doc != NULL ) {
   root = xmlDocGetRootElement(doc);
   print_names(root);
   xmlFreeDoc(doc);
 }
 xmlCleanupParser();
 return 0;

}</lang>

C++

Library: Qt

<lang cpp>/* Using the Qt library's XML parser.

  • /
  1. include <iostream>
  1. include <QDomDocument>
  2. include <QObject>

int main() {

   QDomDocument doc;
   doc.setContent(
      QObject::tr(
         "<Students>\n"
         "<Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />\n"
         "<Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />\n"
         "<Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />\n"
         "<Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">\n"
         "<Pet Type=\"dog\" Name=\"Rover\" />\n"
         "</Student>\n"
         "<Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />\n"
         "</Students>"));
   
   QDomElement n = doc.documentElement().firstChildElement("Student");
   while(!n.isNull()) {
       std::cout << qPrintable(n.attribute("Name")) << std::endl;
       n = n.nextSiblingElement();
   }
   return 0;

}</lang>

Common Lisp

Library: Closure XML

<lang lisp>(defparameter *xml-blob* "<Students>

 <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />
 <Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />
 <Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />
 <Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">
   <Pet Type=\"dog\" Name=\"Rover\" />
 </Student>
 <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />

</Students>")

(let* ((document (cxml:parse *xml-blob* (cxml-dom:make-dom-builder)))

      (students (dom:item (dom:get-elements-by-tag-name document "Students") 0))
      (student-names '()))
 (dom:do-node-list (child (dom:child-nodes students) (nreverse student-names))
   (when (dom:element-p child)
     (push (dom:get-attribute child "Name") student-names))))</lang>

produces<lang lisp>("April" "Bob" "Chad" "Dave" "Émily")</lang>

D

Library: KXML

<lang d>import kxml.xml; char[]xmlinput = "<Students>

 <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />
 <Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />
 <Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />
 <Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">
   <Pet Type=\"dog\" Name=\"Rover\" />
 </Student>
 <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />

</Students>";

void main() {

       auto root = readDocument(xmlinput);
       foreach(students;root.getChildren) if (!students.isCData && students.getName == "Students") {
               // now look for student subnodes
               foreach(student;students.getChildren) if (!student.isCData && student.getName == "Student") {
                       // we found a student!
                       std.stdio.writefln("%s",student.getAttribute("Name"));
               }
               // we only want one, so break out of the loop once we find a match
               break;
       }

}</lang>

Haskell

<lang haskell>import Data.Maybe import Text.XML.Light

students="<Students>"++

       " <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />"++
       " <Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />"++
       " <Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\"/>"++
       " <Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">"++
       "   <Pet Type=\"dog\" Name=\"Rover\" />  </Student>"++
       " <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />"++
       "</Students>"

xmlRead elm name = mapM_ putStrLn

     . concatMap (map (fromJust.findAttr (unqual name)).filterElementsName (== unqual elm))
     . onlyElems.  parseXML</lang>

Show names: <lang haskell>*Main> xmlRead "Student" "Name" students April Bob Chad Dave Émily</lang>

J

J's system includes several XML processing libraries. This task is probably best addressed using XPath (this is the type of problem XPath was designed to solve), but the task description implicitly discourages that method. So we can use the SAX library instead:

<lang j>load'xml/sax'

saxclass 'Students' startElement =: ([: smoutput 'Name' getAttribute~ [)^:('Student'-:]) cocurrent'base'

process_Students_ XML</lang>

April
Bob
Chad
Dave
Émily

and the definition of XML: <lang j>XML=: noun define <Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />

</Students> )</lang>

Java

<lang java>import java.io.IOException; import java.io.StringReader; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory;

public class StudentHandler extends DefaultHandler {

 public static void main(String[] args)throws Exception{
   String xml = "<Students>\n"+
   "<Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />\n"+
   "<Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />\n"+
   "<Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />\n"+
   "<Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">\n"+
   "  <Pet Type=\"dog\" Name=\"Rover\" />\n"+
   "</Student>\n"+
   "<Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />\n"+
   "</Students>";
   StudentHandler handler = new StudentHandler();
   handler.parse(new InputSource(new StringReader(xml)));
 }
 public void parse(InputSource src) throws SAXException, IOException {

XMLReader parser = XMLReaderFactory.createXMLReader();

   parser.setContentHandler(this);
   parser.parse(src);
 }
 @Override
 public void characters(char[] ch, int start, int length) throws SAXException {
   //if there were text as part of the elements, we would deal with it here
   //by adding it to a StringBuffer, but we don't have to for this task
   super.characters(ch, start, length);
 }
 @Override
 public void endElement(String uri, String localName, String qName) throws SAXException {
   //this is where we would get the info from the StringBuffer if we had to,
   //but all we need is attributes
   super.endElement(uri, localName, qName);
 }
 @Override
 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
   if(qName.equals("Student")){
     System.out.println(attributes.getValue("Name"));
   }
 }

}</lang>

OCaml

from the toplevel using the library xml-light: <lang ocaml># #directory "+xml-light" (* or maybe "+site-lib/xml-light" *) ;;

  1. #load "xml-light.cma" ;;
  1. let x = Xml.parse_string "
 <Students>
   <Student Name='April' Gender='F' DateOfBirth='1989-01-02' />
   <Student Name='Bob' Gender='M'  DateOfBirth='1990-03-04' />
   <Student Name='Chad' Gender='M'  DateOfBirth='1991-05-06' />
   <Student Name='Dave' Gender='M'  DateOfBirth='1992-07-08'>
     <Pet Type='dog' Name='Rover' />
   </Student>
   <Student DateOfBirth='1993-09-10' Gender='F' Name='Émily' />
 </Students>"
 in
 Xml.iter (function
   (Xml.Element ("Student", attrs, _)) ->
     (try
       let _, name = 
         List.find (function ("Name", _) -> true | _ -> false) attrs
       in
       print_endline name
     with Not_found -> ())
 | _ -> ()) x
 ;;

April Bob Chad Dave Émily - : unit = ()</lang>

Another solution using the library xmlm: <lang ocaml>#directory "+xmlm"

  1. load "xmlm.cmo"

open Xmlm

let str = "

 <Students>
   <Student Name='April' Gender='F' DateOfBirth='1989-01-02' />
   <Student Name='Bob'   Gender='M' DateOfBirth='1990-03-04' />
   <Student Name='Chad'  Gender='M' DateOfBirth='1991-05-06' />
   <Student Name='Dave'  Gender='M' DateOfBirth='1992-07-08'>
     <Pet Type='dog' Name='Rover' />
   </Student>
   <Student DateOfBirth='1993-09-10' Gender='F' Name='Émily' />
 </Students>"


let xi = make_input(`String(0, str))

let () =

 while not(eoi xi) do
   match Xmlm.input xi with
   | `El_start ((_, "Student"), attrs) ->
       List.iter (function ((_, "Name"), name) -> print_endline name | _ -> ()) attrs
   | _ -> ()
 done</lang>

Python

<lang python>import xml.dom.minidom

doc = """<Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />

</Students>"""

doc = xml.dom.minidom.parseString(doc)

for i in doc.getElementsByTagName("Student"):

   print i.getAttribute("Name")</lang>

R

Library: XML

<lang R>library(XML)

  1. Read in XML string

str <- readLines(tc <- textConnection('<Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />

</Students>')) close(tc) str</lang>

[1] "<Students>"                                                                 
[2] "  <Student Name=\"April\" Gender=\"F\" DateOfBirth=\"1989-01-02\" />"       
[3] "  <Student Name=\"Bob\" Gender=\"M\"  DateOfBirth=\"1990-03-04\" />"        
[4] "  <Student Name=\"Chad\" Gender=\"M\"  DateOfBirth=\"1991-05-06\" />"       
[5] "  <Student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">"         
[6] "    <Pet Type=\"dog\" Name=\"Rover\" />"                                    
[7] "  </Student>"                                                               
[8] "  <Student DateOfBirth=\"1993-09-10\" Gender=\"F\" Name=\"Émily\" />"
[9] "</Students>"

<lang R>#Convert to an XML tree xmltree <- xmlTreeParse(str)

  1. Retrieve the students, and how many there are

students <- xmltree$doc$children$Students nstudents <- length(students)

  1. Get each of their names

studentsnames <- character(nstudents) for(i in 1:nstudents) {

  this.student <- students$children[i]$Student
  studentsnames[i] <- this.student$attributes["Name"]   

}

  1. Change the encoding so that Emily displays correctly

Encoding(studentsnames) <- "UTF-8" studentsnames</lang>

[1] "April" "Bob"   "Chad"  "Dave"  "Émily"

Ruby

Library: REXML

<lang ruby>require 'rexml/document' include REXML

doc = Document.new(File.new("sample.xml"))

  1. or
  2. doc = Document.new(xml_string)
  1. without using xpath

doc.each_recursive do |node|

 puts node.attributes["Name"] if node.name == "Student"

end

  1. using xpath

doc.each_element("*/Student") {|node| puts node.attributes["Name"]}</lang>

Scala

Scala has native XML support, with query constructs similar to XPath and XQuery.

<lang scala>object xmlstudents extends Application {

 val students =
   <Students>
     <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
     <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
     <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
     <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
       <Pet Type="dog" Name="Rover" />
     </Student>
     <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />
   </Students>
 students \ "Student" \\ "@Name" foreach println

}</lang>

Slate

Slate's XML Reader is still being developed at the time of this writing.

<lang slate>slate[1]> [ |tree|

 tree: (Xml SimpleParser newOn: '<Students>
   <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
   <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
   <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
   <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
     <Pet Type="dog" Name="Rover" />
   </Student>
   <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" />
 </Students>') parse.
 tree name = 'Students' ifTrue: [(tree children select: #is: `er <- Xml Element)
                                        do: [|:child| child name = 'Student' ifTrue: [inform: (child attributes at: 'Name' ifAbsent: ['Noname'])]]].

] do. April Bob Chad Dave Émily Nil</lang>

Tcl

Using

Library: tDOM

<lang tcl>package require tdom set tree [dom parse $xml] set studentNodes [$tree getElementsByTagName Student] ;# or: set studentNodes [[$tree documentElement] childNodes]

foreach node $studentNodes {

   puts [$node getAttribute Name]

}</lang>

Using

Library: TclXML

<lang tcl>package require xml set parser [xml::parser -elementstartcommand elem] proc elem {name attlist args} {

   if {$name eq "Student"} {
       puts [dict get $attlist Name]
   }

} $parser parse $xml</lang>

Using just pure-Tcl (originally on http://wiki.tcl.tk/3919): <lang Tcl>proc xml2list xml {

   regsub -all {>\s*<} [string trim $xml " \n\t<>"] "\} \{" xml
   set xml [string map {> "\} \{#text \{" < "\}\} \{"}  $xml]
   set res ""   ;# string to collect the result
   set stack {} ;# track open tags
   set rest {}
   foreach item "{$xml}" {
       switch -regexp -- $item {

^# {append res "{[lrange $item 0 end]} " ; #text item} ^/ { regexp {/(.+)} $item -> tagname ;# end tag set expected [lindex $stack end] set stack [lrange $stack 0 end-1] append res "\}\} "

           }

/$ { # singleton - start and end in one <> group

               regexp {([^ ]+)( (.+))?/$} $item -> tagname - rest
               set rest [lrange [string map {= " "} $rest] 0 end]
               append res "{$tagname [list $rest] {}} "

} default {

               set tagname [lindex $item 0] ;# start tag
               set rest [lrange [string map {= " "} $item] 1 end]
               lappend stack $tagname
               append res "\{$tagname [list $rest] \{"

}

       }
   }
   string map {"\} \}" "\}\}"} [lindex $res 0]   ;#"

} proc deent str {

   regsub -all {&\#x(.+?);} $str {\\u\1} str
   subst -nocommands -novar $str

}

  1. ----------------------- Testing the whole thing:

set xml {<Students>

 <Student Name="April" Gender="F" DateOfBirth="1989-01-02" />
 <Student Name="Bob" Gender="M"  DateOfBirth="1990-03-04" />
 <Student Name="Chad" Gender="M"  DateOfBirth="1991-05-06" />
 <Student Name="Dave" Gender="M"  DateOfBirth="1992-07-08">
   <Pet Type="dog" Name="Rover" />
 </Student>
 <Student DateOfBirth="1993-09-10" Gender="F" Name="Émily" /></Students>

} foreach i [lindex [xml2list $xml] 2] {

   if {[lindex $i 0] eq "Student"} {
       foreach {att val} [lindex $i 1] {
           if {$att eq "Name"} {puts [deent $val]}
       }
   }

}</lang>

Vedit macro language

This implementation finds all Student tags and then displays the contents of their Name parameter. <lang vedit>Repeat(ALL) {

   Search("<Student|X", ERRBREAK)
   #1 = Cur_Pos
   Match_Paren()
   if (Search_Block(/Name=|{",'}/, #1, Cur_Pos, BEGIN+ADVANCE+NOERR+NORESTORE)==0) { Continue }
   #2 = Cur_Pos
   Search(/|{",'}/)
   Type_Block(#2, Cur_Pos)
   Type_Newline

}</lang>

Output:

April
Bob
Chad
Dave
Émily

Visual Basic .NET

<lang vbnet>Dim xml = <Students>

             <Student Name="April"/>
             <Student Name="Bob"/>
             <Student Name="Chad"/>
             <Student Name="Dave"/>
             <Student Name="Emily"/>
          </Students>

Dim names = (From node In xml...<Student> Select node.@Name).ToArray

For Each name In names

    Console.WriteLine(name)

Next</lang>