XML/Input: Difference between revisions

m
m (→‎PEG-based Parsing: allow </foo >; def q(_):)
m (→‎{{header|Wren}}: Minor tidy)
 
(7 intermediate revisions by 4 users not shown)
Line 1,056:
=={{header|C}}==
 
==={{libheader|LibXML}}===
{{uses from|Library|libxml|component1=xmlDoc|component2=xmlNode|component3=xmlReadMemory|component4=xmlDocGetRootElement|component5=xmlFreeDoc|component6=xmlCleanupParser|component7=xmlNode|component8=XML_ELEMENT_NODE|component9=xmlAttr|component10=xmlHasProp}}
{{uses from|Library|C Runtime|component1=printf}}
Line 1,107:
return 0;
}</syntaxhighlight>
 
==={{libheader|Gadget}}===
<p>Gadget is a library for strings handler, not XML handler. But...</p>
<syntaxhighlight lang="c">
#include <gadget/gadget.h>
 
LIB_GADGET_START
 
Main
Assert( Arg_count == 2, end_input );
Get_arg_str( xml_file, 1 );
Assert( Exist_file(xml_file), file_not_exist );
 
char* xml = Load_string(xml_file);
ST_GETTAG field = Unparser( &xml, "Students");
Assert ( field.content, fail_content );
 
while ( Occurs ("Student",field.content ) )
{
ST_GETTAG sub_field = Unparser( &field.content, "Student");
 
if(sub_field.attrib)
{
int i=0;
Iterator up i [ 0: 1: sub_field.len ]
{
if ( strcmp(sub_field.name[i], "Name" )==0 )
{
Get_fn_let( sub_field.attrib[i], Str_tran( sub_field.attrib[i], "&#x00C9;","É" ) );
/* OK... I must write the function that change this diabolic characters :D */
Print "%s\n",sub_field.attrib[i];
break;
}
}
}
Free tag sub_field;
}
Free tag field;
/* Exceptions areas */
Exception( fail_content ){
Msg_red("Not content for \"Students\" field\n");
}
Free secure xml;
Exception( file_not_exist ){
Msg_redf("File \"%s\" not found\n", xml_file);
}
Free secure xml_file;
Exception( end_input ){
Msg_yellow("Use:\n RC_xml <xml_file.xml>");
}
End
</syntaxhighlight>
{{out}}
<pre>
$ ./tests/RC_xml xml_data.xml
April
Bob
Chad
Dave
Émily
 
$ ./tests/RC_xml somefile.xml
File "somefile.xml" not found
 
</pre>
<p>File: xml_data.xml:</p>
<syntaxhighlight 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="&#x00C9;mily" />
</Students></syntaxhighlight>
 
=={{header|C sharp}}==
Line 1,598 ⟶ 1,680:
&mily
</pre>
 
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<syntaxhighlight lang="vb">Data 32, 173, 189, 156, 207, 190, 221, 245, 249, 184, 166, 174, 170, 32, 169, 238
Data 248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168
Data 183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216
Data 209, 165, 227, 224, 226, 229, 153, 158, 157, 235, 233, 234, 154, 237, 232, 225
Data 133, 160, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139
Data 208, 164, 149, 162, 147, 228, 148, 246, 155, 151, 163, 150, 129, 236, 231, 152
 
Dim Shared As Integer numCodes, initCode
initCode = 160
numCodes = 255 - initCode + 1
 
Dim Shared As Integer codes(numCodes)
For i As Integer = 0 To numCodes - 1 : Read codes(i)
Next i
 
Function codeConversion(charcode As Integer, tocode As Integer = False) As Integer
If tocode Then
For i As Integer = 0 To numCodes - 1
If codes(i) = charcode Then Return i + initCode
Next i
Else
Return codes(charcode - initCode)
End If
End Function
 
Function convASCII(nombre As String, mark As String) As String
Dim As Integer p, c, lm = Len(mark)
Do
p = Instr(p, nombre, mark)
If p = 0 Then Exit Do
c = Valint(Mid(nombre, p + lm, 4))
c = codeConversion(c)
nombre = Left(nombre, p-1) + Chr(c) + Right(nombre, Len(nombre) - (p + lm + 4))
p += 1
Loop
Return nombre
End Function
 
Dim As String strXml = "<Students>"
strXml += " <Student Name=\'April\' Gender=\'F\' DateOfBirth=\'1989-01-02\' />"
strXml += " <Student Name=\'Bob\' Gender=\'M\' DateOfBirth=\'1990-03-04\' />"
strXml += " <Student Name=\'Chad\' Gender=\'M\' DateOfBirth=\'1991-05-06\' />"
strXml += " <Student Name=\'Dave\' Gender=\'M\' DateOfBirth=\'1992-07-08\'>"
strXml += " <Pet Type=\'dog\' Name=\'Rover\' />"
strXml += " </Student>"
strXml += " <Student DateOfBirth=\'1993-09-10\' Gender=\'F\' Name=\'&#x00C9;mily\' />"
strXml += "</Students>"
 
Dim As String tag1 = "<Student"
Dim As String tag2 = "Name=\'", nombre
Dim As Integer ltag = Len(tag2), p = 1, p2
 
Do
p = Instr(p, strXml, tag1)
If p = 0 Then Exit Do
p = Instr(p, strXml, tag2)
p += ltag
p2 = Instr(p, strXml, "\'")
nombre = convASCII(Mid(strXml, p, p2 - p), "&#x")
Print nombre
Loop
 
Sleep</syntaxhighlight>
{{out}}
<pre>April
Bob
Chad
Dave
&#x00C9;mily</pre>
 
=={{header|FutureBasic}}==
Line 1,991 ⟶ 2,146:
* (2) https://cs.lmu.edu/~ray/notes/xmlgrammar/
====PEG Infrastructure====
The jq module at [[:Category:Jq/peg.jq]] can be included by copying it to a file,
and adding an `include` statement to top of the main program, e.g. as follows:
<syntaxhighlight lang=jq>
include "peg" {search: "."};
# PEG to jq transcription is based on these equivalences:
</syntaxhighlight>
# Sequence: e1 e2 e1 | e2
# Ordered choice: e1 / e2 e1 // e2
# Zero-or-more: e* star(E)
# One-or-more: e+ plus(E)
# Optional: e? optional(E)
# And-predicate: &e amp(E) # no input is consumed
# Not-predicate: !e neg(E) # no input is consumed
 
# The idea is to pass a JSON object {remainder:_, result:_ } through a
# pipeline, consuming the text in .remainder and building up .result.
 
def star(E): ((E | star(E)) // .) ;
def plus(E): E | (plus(E) // . );
def optional(E): (E // .);
def amp(E): . as $in | E | $in;
def neg(E): select( [E] == [] );
 
### Helper functions:
 
# Consume a regular expression rooted at the start of .remainder, or emit empty;
# on success, update .remainder and set .match but do NOT update .result
def consume($re):
# on failure, match yields empty
(.remainder | match("^" + $re)) as $match
| .remainder |= .[$match.length :]
| .match = $match.string;
 
def parse($re):
consume($re)
| .result = .result + [.match] ;
 
# consume the literal string $s
def q($s):
select(.remainder | startswith($s))
| .remainder |= .[$s | length :] ;
 
def literal($s):
q($s)
| .result += [$s];
 
# Tagging
def box(E):
((.result = null) | E) as $e
| .remainder = $e.remainder
| .result += [$e.result] # the magic sauce
;
 
def box(name; E):
((.result = null) | E) as $e
| .remainder = $e.remainder
| .result += [{(name): (try ($e.result|join("")) catch $e.result) }] # the magic sauce
;
 
def objectify(E):
box(E)
| .result[-1] |= {(.[0]): .[1:]} ;
 
def keyvalue(E):
box(E)
| .result[-1] |= {(.[0]): .[1]} ;
 
# optional whitespace
def ws: consume("[ \n\r\t]*");
 
def string_except($regex):
box(star(neg( parse($regex) ) | parse("."))) | .result[-1] |= add;
 
</syntaxhighlight>
====XML Grammar====
<syntaxhighlight lang=jq>
Line 3,550 ⟶ 3,641:
&#x00C9;mily
Nil</syntaxhighlight>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">
import Foundation
 
let xmlString = """
<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="&#x00C9;mily" />
</Students>
"""
if let xmlData = xmlString.data(using: .utf8) {
do {
let doc = try XMLDocument(data: xmlData)
print("Using XPath:")
for node in try doc.nodes(forXPath: "/Students/Student/@Name") {
guard let name = node.stringValue else { continue }
print(name)
}
print("Using node walk")
if let root = doc.rootElement() {
for child in root.elements(forName: "Student") {
guard let name = child.attribute(forName: "Name")?.stringValue else { continue }
print(name)
}
}
} catch {
debugPrint(error)
}
}
</syntaxhighlight>
Output:
<syntaxhighlight lang="shell">
~ % ./XMLInput
Using XPath:
April
Bob
Chad
Dave
Émily
Using node walk
April
Bob
Chad
Dave
Émily
</syntaxhighlight>
 
=={{header|Tcl}}==
Line 3,778 ⟶ 3,921:
{{libheader|Wren-fmt}}
Wren doesn't currently have an XML parser though we don't really need one for this task as string pattern matching is sufficient to extract the student names.
<syntaxhighlight lang="ecmascriptwren">import "./pattern" for Pattern
import "./fmt" for Conv
 
var xml =
Line 3,824 ⟶ 3,967:
{{libheader|Wren-xsequence}}
Since the first version was written, the above XML parser has appeared and support for 'raw' strings has also been added to the language. Consequently, the solution can now be rewritten as follows, the output being the same as before.
<syntaxhighlight lang="ecmascriptwren">import "./xsequence" for XDocument
 
var xml = """
9,476

edits