mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-30 05:39:12 +02:00
Add new XML functions required for building documentation.
This commit is contained in:
parent
8f319b6fd3
commit
217584a2c4
@ -4,6 +4,31 @@ XML Handler Extensions
|
||||
// Include core module
|
||||
#include "common/type/xml.c"
|
||||
|
||||
#include "build/common/xml.h"
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
XmlDocument *
|
||||
xmlDocumentNewParam(const String *const rootNode, const XmlDocumentNewParam param)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, rootNode);
|
||||
FUNCTION_TEST_PARAM(STRING, param.dtdName);
|
||||
FUNCTION_TEST_PARAM(STRING, param.dtdFile);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(rootNode != NULL);
|
||||
|
||||
XmlDocument *const result = xmlDocumentNew(rootNode);
|
||||
|
||||
if (param.dtdName != NULL)
|
||||
{
|
||||
ASSERT(param.dtdFile != NULL);
|
||||
xmlCreateIntSubset(result->xml, (unsigned char *)strZ(param.dtdName), NULL, (unsigned char *)strZ(param.dtdFile));
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(XML_DOCUMENT, result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
xmlNodeAttribute(const XmlNode *this, const String *name)
|
||||
@ -27,3 +52,74 @@ xmlNodeAttribute(const XmlNode *this, const String *name)
|
||||
|
||||
FUNCTION_TEST_RETURN(STRING, result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
xmlNodeAttributeSet(XmlNode *const this, const String *const name, const String *const value)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(XML_NODE, this);
|
||||
FUNCTION_TEST_PARAM(STRING, name);
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(name != NULL);
|
||||
ASSERT(value != NULL);
|
||||
|
||||
xmlSetProp(this->node, (unsigned char *)strZ(name), (unsigned char *)strZ(value));
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
xmlNodeChildAdd(XmlNode *const this, const XmlNode *const child)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(XML_NODE, this);
|
||||
FUNCTION_TEST_PARAM(XML_NODE, child);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(child != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
for (xmlNodePtr currentNodeRaw = child->node->children; currentNodeRaw != NULL; currentNodeRaw = currentNodeRaw->next)
|
||||
{
|
||||
// Skip comments
|
||||
if (currentNodeRaw->type == XML_COMMENT_NODE)
|
||||
continue;
|
||||
|
||||
// Copy all child nodes (only node and text types are copied)
|
||||
XmlNode *const currentNode = xmlNodeNew(currentNodeRaw);
|
||||
|
||||
if (currentNode->node->type == XML_ELEMENT_NODE)
|
||||
{
|
||||
XmlNode *const node = xmlNodeAdd(this, STR((char *)currentNode->node->name));
|
||||
|
||||
// Copy node attributes
|
||||
for (xmlAttrPtr currentAttr = currentNode->node->properties; currentAttr != NULL; currentAttr = currentAttr->next)
|
||||
{
|
||||
xmlNodeAttributeSet(
|
||||
node, STR((char *)currentAttr->name), xmlNodeAttribute(currentNode, STR((char *)currentAttr->name)));
|
||||
}
|
||||
|
||||
// Recurse to copy child nodes
|
||||
xmlNodeChildAdd(node, currentNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_FMT(
|
||||
AssertError, currentNode->node->type == XML_TEXT_NODE, "unknown type %u in node '%s'", currentNode->node->type,
|
||||
(char *)currentNode->node->name);
|
||||
|
||||
xmlNodeContentSet(this, xmlNodeContent(currentNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
@ -6,10 +6,32 @@ XML Handler Extensions
|
||||
|
||||
#include "common/type/xml.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructors
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct XmlDocumentNewParam
|
||||
{
|
||||
VAR_PARAM_HEADER;
|
||||
const String *dtdName; // DTD name, if any
|
||||
const String *dtdFile; // DTD file (must be set if dtdName is set)
|
||||
} XmlDocumentNewParam;
|
||||
|
||||
#define xmlDocumentNewP(rootNode, ...) \
|
||||
xmlDocumentNewParam(rootNode, (XmlDocumentNewParam){VAR_PARAM_INIT, __VA_ARGS__})
|
||||
|
||||
XmlDocument *xmlDocumentNewParam(const String *rootNode, XmlDocumentNewParam param);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Node Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Node attribute
|
||||
// Get/set node attribute
|
||||
String *xmlNodeAttribute(const XmlNode *this, const String *name);
|
||||
void xmlNodeAttributeSet(XmlNode *this, const String *name, const String *value);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Add all child nodes to another node
|
||||
void xmlNodeChildAdd(XmlNode *this, const XmlNode *child);
|
||||
|
||||
#endif
|
||||
|
@ -84,7 +84,7 @@ testRun(void)
|
||||
|
||||
// Create an empty document, add data to it, and output xml
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ASSIGN(xmlDocument, xmlDocumentNew(STRDEF("CompleteMultipartUpload")), "new xml with root node");
|
||||
TEST_ASSIGN(xmlDocument, xmlDocumentNewP(STRDEF("CompleteMultipartUpload")), "new xml with root node");
|
||||
|
||||
XmlNode *partNode = NULL;
|
||||
TEST_ASSIGN(partNode, xmlNodeAdd(xmlDocumentRoot(xmlDocument), STRDEF("Part")), "create part node 1");
|
||||
@ -103,6 +103,38 @@ testRun(void)
|
||||
"<Part><PartNumber>2</PartNumber><ETag>E2</ETag></Part>"
|
||||
"</CompleteMultipartUpload>\n",
|
||||
"get xml");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("copy xml between documents");
|
||||
|
||||
XmlDocument *xmlDocument2 = NULL;
|
||||
|
||||
TEST_ASSIGN(
|
||||
xmlDocument, xmlDocumentNewP(STRDEF("doc1"), .dtdName = STRDEF("doc"), .dtdFile = STRDEF("doc.dtd")),
|
||||
"new xml with dtd");
|
||||
TEST_ASSIGN(
|
||||
xmlDocument2,
|
||||
xmlDocumentNewBuf(
|
||||
BUFSTRDEF(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<doc2>\n"
|
||||
" <!-- comment -->\n"
|
||||
" text55\n"
|
||||
" <name id=\"id55\">name55</name>\n"
|
||||
"</doc2>")),
|
||||
"valid xml");
|
||||
|
||||
TEST_RESULT_VOID(xmlNodeChildAdd(xmlDocumentRoot(xmlDocument), xmlDocumentRoot(xmlDocument2)), "copy xml");
|
||||
TEST_RESULT_STR_Z(
|
||||
strNewBuf(xmlDocumentBuf(xmlDocument)),
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
|
||||
"<doc1>\n"
|
||||
" \n"
|
||||
" text55\n"
|
||||
" <name id=\"id55\">name55</name>\n"
|
||||
"</doc1>\n",
|
||||
"get xml");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RETURN_VOID();
|
||||
|
Loading…
x
Reference in New Issue
Block a user