zipped
This commit is contained in:
parent
b35c157126
commit
466c18e55e
|
@ -47,4 +47,5 @@ check-am:
|
|||
@echo "optional..."; ./dexter test/optional.dex test/optional.html | diff test/optional.json - && echo " success."
|
||||
@echo "malformed-function..."; ./dexter test/malformed-function.dex test/malformed-function.html | diff test/malformed-function.json - && echo " success."
|
||||
@echo "empty..."; ./dexter test/empty.dex test/empty.html | diff test/empty.json - && echo " success."
|
||||
@echo "hn..."; ./dexter test/hn.dex test/hn.html | diff test/hn.json - && echo " success."
|
||||
|
|
@ -750,6 +750,7 @@ check-am:
|
|||
@echo "optional..."; ./dexter test/optional.dex test/optional.html | diff test/optional.json - && echo " success."
|
||||
@echo "malformed-function..."; ./dexter test/malformed-function.dex test/malformed-function.html | diff test/malformed-function.json - && echo " success."
|
||||
@echo "empty..."; ./dexter test/empty.dex test/empty.html | diff test/empty.json - && echo " success."
|
||||
@echo "hn..."; ./dexter test/hn.dex test/hn.html | diff test/hn.json - && echo " success."
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
|
99
dexter.c
99
dexter.c
|
@ -223,6 +223,7 @@ static contextPtr new_context(struct json_object * json, struct printbuf *buf) {
|
|||
c->string = 0;
|
||||
c->flags = 0;
|
||||
c->keys = NULL;
|
||||
c->zipped = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -280,6 +281,14 @@ static char* optional(contextPtr c) {
|
|||
return (c->flags & DEX_OPTIONAL) ? " optional=\"true\"" : "";
|
||||
}
|
||||
|
||||
static bool
|
||||
all_strings(struct json_object * json) {
|
||||
json_object_object_foreach(json, key, val) {
|
||||
if(!json_object_is_type(val, json_type_string)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void __dex_recurse(contextPtr context) {
|
||||
// printf("a\n");
|
||||
char* tmp;
|
||||
|
@ -290,79 +299,89 @@ void __dex_recurse(contextPtr context) {
|
|||
c = deeper_context(context, key, val);
|
||||
sprintbuf(c->buf, "<%s%s>\n", c->tag, optional(c));
|
||||
if(c->string) {
|
||||
if(c->array) {
|
||||
if(c->array || context->zipped) {
|
||||
if(c->filter){
|
||||
// printf("b\n");
|
||||
sprintbuf(c->buf, "<dexter:groups optional=\"true\"><xsl:for-each select=\"%s\"><dexter:group optional=\"true\">\n", c->filter);
|
||||
sprintbuf(c->buf, "<xsl:value-of select=\"%s\" />\n", c->raw_expr);
|
||||
sprintbuf(c->buf, "</dexter:group></xsl:for-each></dexter:groups>\n");
|
||||
} else {
|
||||
// printf("c\n");
|
||||
sprintbuf(c->buf, "<dexter:groups optional=\"true\"><xsl:for-each select=\"%s\"><dexter:group optional=\"true\">\n", c->expr);
|
||||
sprintbuf(c->buf, "<xsl:value-of select=\".\" />\n");
|
||||
sprintbuf(c->buf, "</dexter:group></xsl:for-each></dexter:groups>\n");
|
||||
}
|
||||
} else {
|
||||
if(c->filter){
|
||||
// printf("d\n");
|
||||
sprintbuf(c->buf, "<xsl:for-each select=\"%s\"><xsl:if test=\"position()=1\">\n", c->filter);
|
||||
sprintbuf(c->buf, "<xsl:value-of select=\"%s\" />\n", c->raw_expr);
|
||||
sprintbuf(c->buf, "</xsl:if></xsl:for-each>\n");
|
||||
} else {
|
||||
// printf("e\n");
|
||||
sprintbuf(c->buf, "<xsl:value-of select=\"%s\" />\n", c->expr);
|
||||
}
|
||||
}
|
||||
} else { // if c->object !string
|
||||
if(c->array) { // scoped
|
||||
|
||||
if(c->filter != NULL) {
|
||||
|
||||
// printf("e\n");
|
||||
// printf("f\n");
|
||||
sprintbuf(c->buf, "<dexter:groups optional=\"true\"><xsl:for-each select=\"%s\"><dexter:group optional=\"true\">\n", c->filter);
|
||||
__dex_recurse(c);
|
||||
sprintbuf(c->buf, "</dexter:group></xsl:for-each></dexter:groups>\n");
|
||||
} else { // magic
|
||||
|
||||
// printf("f\n");
|
||||
sprintbuf(c->buf, "<xsl:variable name=\"%s__context\" select=\".\"/>\n", c->name);
|
||||
dex_parsing_context = c;
|
||||
char * str = inner_key_of(c->json);
|
||||
if(str != NULL) {
|
||||
tmp = myparse(astrdup(str));
|
||||
sprintbuf(c->buf, "<dexter:groups optional=\"true\"><xsl:for-each select=\"%s\">\n", filter_intersection(context->magic, tmp));
|
||||
} else { // magic
|
||||
if(all_strings(c->json)) {
|
||||
c->magic = NULL;
|
||||
c->zipped = 1;
|
||||
sprintbuf(c->buf, "<dexter:zipped>\n");
|
||||
__dex_recurse(c);
|
||||
sprintbuf(c->buf, "</dexter:zipped>\n");
|
||||
} else {
|
||||
// printf("h\n");
|
||||
sprintbuf(c->buf, "<xsl:variable name=\"%s__context\" select=\".\"/>\n", c->name);
|
||||
dex_parsing_context = c;
|
||||
char * str = inner_key_of(c->json);
|
||||
if(str != NULL) {
|
||||
// printf("i\n");
|
||||
tmp = myparse(astrdup(str));
|
||||
sprintbuf(c->buf, "<dexter:groups optional=\"true\"><xsl:for-each select=\"%s\">\n", filter_intersection(context->magic, tmp));
|
||||
|
||||
// keys
|
||||
keys = dex_alloc(sizeof(key_node));
|
||||
keys->name = c->name;
|
||||
keys->use = full_expr(c, tmp);
|
||||
keys->next = c->keys;
|
||||
c->keys = keys;
|
||||
// keys
|
||||
keys = dex_alloc(sizeof(key_node));
|
||||
keys->name = c->name;
|
||||
keys->use = full_expr(c, tmp);
|
||||
keys->next = c->keys;
|
||||
c->keys = keys;
|
||||
|
||||
buf = printbuf_new();
|
||||
buf = printbuf_new();
|
||||
|
||||
sprintbuf(buf, "concat(");
|
||||
while(keys != NULL){
|
||||
sprintbuf(buf, "count(set:intersection(following::*, %s)), '-',", keys->use);
|
||||
keys = keys->next;
|
||||
}
|
||||
sprintbuf(buf, "'')");
|
||||
tmp = astrdup(buf->buf);
|
||||
printbuf_free(buf);
|
||||
sprintbuf(buf, "concat(");
|
||||
while(keys != NULL){
|
||||
sprintbuf(buf, "count(set:intersection(following::*, %s)), '-',", keys->use);
|
||||
keys = keys->next;
|
||||
}
|
||||
sprintbuf(buf, "'')");
|
||||
tmp = astrdup(buf->buf);
|
||||
printbuf_free(buf);
|
||||
|
||||
sprintbuf(c->key_buf, "<xsl:key name=\"%s__key\" match=\"%s\" use=\"%s\"/>\n", c->name,
|
||||
full_expr(c, "./descendant-or-self::*"),
|
||||
tmp
|
||||
);
|
||||
sprintbuf(c->key_buf, "<xsl:key name=\"%s__key\" match=\"%s\" use=\"%s\"/>\n", c->name,
|
||||
full_expr(c, "./descendant-or-self::*"),
|
||||
tmp
|
||||
);
|
||||
|
||||
sprintbuf(c->buf, "<xsl:variable name=\"%s__index\" select=\"%s\"/>\n", c->name, tmp);
|
||||
sprintbuf(c->buf, "<xsl:for-each select=\"$%s__context\"><dexter:group optional=\"true\">\n", c->name);
|
||||
__dex_recurse(c);
|
||||
sprintbuf(c->buf, "</dexter:group></xsl:for-each></xsl:for-each></dexter:groups>\n");
|
||||
}
|
||||
sprintbuf(c->buf, "<xsl:variable name=\"%s__index\" select=\"%s\"/>\n", c->name, tmp);
|
||||
sprintbuf(c->buf, "<xsl:for-each select=\"$%s__context\"><dexter:group optional=\"true\">\n", c->name);
|
||||
__dex_recurse(c);
|
||||
sprintbuf(c->buf, "</dexter:group></xsl:for-each></xsl:for-each></dexter:groups>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// printf("c\n");
|
||||
// printf("j\n");
|
||||
if(c->filter == NULL) {
|
||||
__dex_recurse(c);
|
||||
} else {
|
||||
} else {
|
||||
// printf("k\n");
|
||||
sprintbuf(c->buf, "<xsl:for-each select=\"%s\"><xsl:if test=\"position() = 1\">\n", c->filter);
|
||||
__dex_recurse(c);
|
||||
sprintbuf(c->buf, "</xsl:if></xsl:for-each>\n");
|
||||
|
|
1
dexter.h
1
dexter.h
|
@ -53,6 +53,7 @@ typedef struct __dex_context {
|
|||
int array;
|
||||
int string;
|
||||
int flags;
|
||||
int zipped;
|
||||
} dex_context;
|
||||
|
||||
typedef dex_context * contextPtr;
|
||||
|
|
2
libtool
2
libtool
|
@ -2,7 +2,7 @@
|
|||
|
||||
# libtool - Provide generalized library-building support services.
|
||||
# Generated automatically by config.status (dexterc) 1.0
|
||||
# Libtool was configured on host kyle-maxwells-macbook.local:
|
||||
# Libtool was configured on host 111.flood.pivotallabs.com:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
#
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
|
||||
|
|
2
parser.y
2
parser.y
|
@ -230,8 +230,6 @@ PrimaryExpr
|
|||
|
||||
FunctionCall
|
||||
: FunctionName LPAREN Arguments RPAREN { $$ = astrcat4(xpath_alias($1), $2, $3, $4); }
|
||||
| FunctionName LPAREN Arguments { yyerror("Unclosed parenthesis"); }
|
||||
| FunctionName LPAREN Arguments RPAREN RPAREN { yyerror("Too many parenthesis"); }
|
||||
;
|
||||
Arguments
|
||||
: ArgumentSet
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"articles": [ {
|
||||
"title": ".title a",
|
||||
"link": ".title a @href",
|
||||
"comment_count(.subtext a:nth-child(3))": "number(regex:match(., '[0-9]+', ''))",
|
||||
"comment_link": ".subtext a:nth-child(3) @href"
|
||||
} ]
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
util.c
3
util.c
|
@ -107,7 +107,8 @@ char* sprintbuf_dex_header(struct printbuf *buf) {
|
|||
sprintbuf(buf, " xmlns:exsl=\"http://exslt.org/common\"");
|
||||
sprintbuf(buf, " xmlns:saxon=\"http://icl.com/saxon\"");
|
||||
sprintbuf(buf, " xmlns:regexp=\"http://exslt.org/regular-expressions\"");
|
||||
sprintbuf(buf, " extension-element-prefixes=\"dex str math set func dyn exsl saxon user date regexp\"");
|
||||
sprintbuf(buf, " xmlns:regex=\"http://exslt.org/regular-expressions\"");
|
||||
sprintbuf(buf, " extension-element-prefixes=\"dex str math set func dyn exsl saxon user date regexp regex\"");
|
||||
sprintbuf(buf, ">\n");
|
||||
sprintbuf(buf, "<xsl:output method=\"xml\" indent=\"yes\"/>\n");
|
||||
sprintbuf(buf, "<xsl:strip-space elements=\"*\"/>\n");
|
||||
|
|
41
xml2json.c
41
xml2json.c
|
@ -1,7 +1,11 @@
|
|||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/debugXML.h>
|
||||
#include <json/json.h>
|
||||
#include "xml2json.h"
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static struct json_object * _xml2json(xmlNodePtr xml) {
|
||||
if(xml == NULL) return NULL;
|
||||
|
@ -20,7 +24,42 @@ static struct json_object * _xml2json(xmlNodePtr xml) {
|
|||
child = child->next;
|
||||
}
|
||||
} else if(!strcmp(xml->ns->prefix, "dexter")) {
|
||||
if(!strcmp(xml->name, "groups")) {
|
||||
if(!strcmp(xml->name, "zipped")) {
|
||||
int len = 0;
|
||||
xmlNodePtr ptr = xml->children;
|
||||
while(ptr != NULL){
|
||||
len++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
xmlNodePtr *ptrs = (xmlNodePtr *) malloc(len * sizeof(xmlNodePtr));
|
||||
char **names = (char**) malloc(len * sizeof(char*));
|
||||
for(int i = 0; i < len; i++) {
|
||||
// zip named groups
|
||||
ptrs[i] = child->children->children;
|
||||
names[i] = child->name;
|
||||
child = child->next;
|
||||
}
|
||||
json = json_object_new_array();
|
||||
bool legit = true;
|
||||
while(legit) {
|
||||
for(int i = 0; i < len; i++) {
|
||||
// fprintf(stderr, "name: %s\n", names[i]);
|
||||
// xmlDebugDumpNode(stderr, ptrs[i], 2);
|
||||
// exit(1);
|
||||
legit &= ptrs[i] != NULL;
|
||||
}
|
||||
if(legit) {
|
||||
struct json_object * inner = json_object_new_object();
|
||||
for(int i = 0; i < len; i++) {
|
||||
json_object_object_add(inner, names[i], xml2json(ptrs[i]->children));
|
||||
ptrs[i] = ptrs[i]->next;
|
||||
}
|
||||
json_object_array_add(json, inner);
|
||||
}
|
||||
}
|
||||
free(ptrs);
|
||||
free(names);
|
||||
} else if(!strcmp(xml->name, "groups")) {
|
||||
json = json_object_new_array();
|
||||
while(child != NULL) {
|
||||
json_object_array_add(json, xml2json(child->children));
|
||||
|
|
Loading…
Reference in New Issue