From 5dbfb96afe0c243dc4358e9ea1a2b1d02170b1a5 Mon Sep 17 00:00:00 2001 From: Omikhleia Date: Fri, 6 Dec 2024 14:17:51 +0100 Subject: [PATCH 1/2] feat(lxp): Add parser option to disable attribute positions --- docs/manual.html | 14 +++++++++----- src/lxplib.c | 5 ++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/manual.html b/docs/manual.html index 607e7c7..f506f23 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -144,13 +144,16 @@

Finishing parsing

Constructor

-
lxp.new(callbacks [, separator[, merge_character_data]])
+
lxp.new(callbacks [, separator[, merge_character_data, [attribute_position]]])
The parser is created by a call to the function lxp.new, which returns the created parser or raises a Lua error. It receives the callbacks table and optionally the parser separator character used in the namespace expanded element names. If merge_character_data is false then LuaExpat will not combine multiple - CharacterData calls into one. For more info on this behaviour see CharacterData below.
+ CharacterData calls into one. For more info on this behaviour see CharacterData below. + If attribute_position is false then LuaExpat will not include the + attribute position in the attributes table. For more info on this behaviour see + StartElement below.

Methods

@@ -424,7 +427,8 @@

Callbacks

every attribute in the element start tag and entries for the default attributes for that element.
The attributes are listed by name (including the inherited ones) - and by position (inherited attributes are not considered in the + and, unless attribute_position is set to false when calling + lxp.new(), by position (inherited attributes are not considered in the position list).
As an example if the book element has attributes author, title and an optional format @@ -434,8 +438,8 @@

Callbacks

would be represented as
-{[1] = "Ierusalimschy, Roberto",
- [2] = "Programming in Lua",
+{[1] = "author",
+ [2] = "title",
  author = "Ierusalimschy, Roberto",
  format = "printed",
  title = "Programming in Lua"}
diff --git a/src/lxplib.c b/src/lxplib.c
index 01323fa..a11b036 100644
--- a/src/lxplib.c
+++ b/src/lxplib.c
@@ -48,6 +48,7 @@ struct lxp_userdata {
   enum XPState state;
   luaL_Buffer *b;  /* to concatenate sequences of cdata pieces */
   int bufferCharData; /* whether to buffer cdata pieces */
+  int attributePosition; /* whether to include attribute position */
 };
 
 typedef struct lxp_userdata lxp_userdata;
@@ -201,7 +202,7 @@ static void f_DefaultExpand (void *ud, const char *data, int len) {
 static void f_StartElement (void *ud, const char *name, const char **attrs) {
   lxp_userdata *xpu = (lxp_userdata *)ud;
   lua_State *L = xpu->L;
-  int lastspec = XML_GetSpecifiedAttributeCount(xpu->parser) / 2;
+  int lastspec = xpu->attributePosition != 0 ? XML_GetSpecifiedAttributeCount(xpu->parser) / 2 : 0;
   int i = 1;
   if (getHandle(xpu, StartElementKey) == 0) return;  /* no handle */
   lua_pushstring(L, name);
@@ -546,9 +547,11 @@ static void checkcallbacks (lua_State *L) {
 
 static int lxp_make_parser (lua_State *L) {
   XML_Parser p;
+  int attributePosition = (lua_type(L, 4) != LUA_TBOOLEAN) || (lua_toboolean(L, 4) != 0);
   int bufferCharData = (lua_type(L, 3) != LUA_TBOOLEAN) || (lua_toboolean(L, 3) != 0);
   char sep = *luaL_optstring(L, 2, "");
   lxp_userdata *xpu = createlxp(L);
+  xpu->attributePosition = attributePosition;
   xpu->bufferCharData = bufferCharData;
   p = xpu->parser = (sep == '\0') ? XML_ParserCreate(NULL) :
                                     XML_ParserCreateNS(NULL, sep);

From d61240204b36f09a9d5d9bebd1cdcaeaf7ec6379 Mon Sep 17 00:00:00 2001
From: Omikhleia 
Date: Tue, 7 Jan 2025 23:32:24 +0100
Subject: [PATCH 2/2] docs: fix description of attribute_position in the
 documentation

Co-authored-by: Caleb Maclennan 
---
 docs/manual.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/manual.html b/docs/manual.html
index f506f23..8ff7b63 100644
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -144,7 +144,7 @@ 

Finishing parsing

Constructor

-
lxp.new(callbacks [, separator[, merge_character_data, [attribute_position]]])
+
lxp.new(callbacks [, separator[, merge_character_data[, attribute_position]]])
The parser is created by a call to the function lxp.new, which returns the created parser or raises a Lua error. It receives the callbacks table and optionally the parser