summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan.goodliffe@octal.co.uk>2023-04-06 09:17:48 +0100
committerDan Goodliffe <dan.goodliffe@octal.co.uk>2023-04-06 09:17:48 +0100
commit5109bffbcd72d003d2d4c2c5e0d7c366c3b5e2b4 (patch)
treeb6816d1b1d34a67db59985f491260ea5a77411dd
parentMove to b2 install path (diff)
downloadicespider-0.8.2.tar.bz2
icespider-0.8.2.tar.xz
icespider-0.8.2.zip
Fix writing of XML document after XSL transformicespider-0.8.2
Addresses issue where document headers such as the XML declaration were omitted
-rw-r--r--icespider/unittests/testApp.cpp16
-rw-r--r--icespider/unittests/testRoutes.json39
-rw-r--r--icespider/unittests/xslt/transformxml.xslt11
-rw-r--r--icespider/xslt/xsltStreamSerializer.cpp5
4 files changed, 59 insertions, 12 deletions
diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp
index efd328d..9f84999 100644
--- a/icespider/unittests/testApp.cpp
+++ b/icespider/unittests/testApp.cpp
@@ -385,10 +385,26 @@ BOOST_AUTO_TEST_CASE(testCallIndexAcceptXml)
auto h = requestXml.getResponseHeaders();
BOOST_REQUIRE_EQUAL(h["Status"], "200 OK");
BOOST_REQUIRE_EQUAL(h["Content-Type"], "application/xml");
+ BOOST_TEST_INFO(requestXml.output.view());
+ BOOST_REQUIRE_NE(requestXml.output.view().find("<?xml version"), std::string_view::npos);
auto v = Slicer::DeserializeAny<Slicer::XmlStreamDeserializer, TestIceSpider::SomeModelPtr>(requestXml.output);
BOOST_REQUIRE_EQUAL(v->value, "index");
}
+BOOST_AUTO_TEST_CASE(testCallIndexAcceptXsltXml)
+{
+ TestRequest requestXml(this, HttpMethod::GET, "/");
+ requestXml.hdr["Accept"] = "application/xml+test";
+ process(&requestXml);
+ auto h = requestXml.getResponseHeaders();
+ BOOST_REQUIRE_EQUAL(h["Status"], "200 OK");
+ BOOST_REQUIRE_EQUAL(h["Content-Type"], "application/xml+test");
+ BOOST_TEST_INFO(requestXml.output.view());
+ BOOST_REQUIRE_NE(requestXml.output.view().find("<?xml version"), std::string_view::npos);
+ xmlpp::DomParser d;
+ d.parse_stream(requestXml.output);
+}
+
BOOST_AUTO_TEST_CASE(testCallIndexAcceptTextHtml)
{
TestRequest requestHtml(this, HttpMethod::GET, "/");
diff --git a/icespider/unittests/testRoutes.json b/icespider/unittests/testRoutes.json
index e3f2298..8dd87c3 100644
--- a/icespider/unittests/testRoutes.json
+++ b/icespider/unittests/testRoutes.json
@@ -1,10 +1,17 @@
{
"name": "common",
- "headers": [ "xsltStreamSerializer.h", "base2.h" ],
+ "headers": [
+ "xsltStreamSerializer.h",
+ "base2.h"
+ ],
"routeBases": {
"base1": {
- "proxies": ["TestIceSpider.TestApi"],
- "functions": [ "void doNothing()" ]
+ "proxies": [
+ "TestIceSpider.TestApi"
+ ],
+ "functions": [
+ "void doNothing()"
+ ]
}
},
"routes": {
@@ -14,11 +21,24 @@
"outputSerializers": {
"text/html": {
"serializer": "IceSpider.XsltStreamSerializer",
- "params": [ "\"xslt/transform.xslt\"" ]
+ "params": [
+ "\"xslt/transform.xslt\""
+ ]
+ },
+ "application/xml+test": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [
+ "\"xslt/transformxml.xslt\""
+ ]
}
},
- "bases": [ "base1", "base2" ],
- "mutators": [ "testMutate" ],
+ "bases": [
+ "base1",
+ "base2"
+ ],
+ "mutators": [
+ "testMutate"
+ ],
"operation": "TestIceSpider.TestApi.index"
},
"simple": {
@@ -66,7 +86,7 @@
}
}
},
- "itemWithDefault":{
+ "itemWithDefault": {
"path": "/item/{s}/{i}",
"method": "GET",
"operation": "TestIceSpider.TestApi.withParams"
@@ -109,7 +129,9 @@
"outputSerializers": {
"application/xml": {
"serializer": "IceSpider.XsltStreamSerializer",
- "params": [ "\"xslt/transform.xslt\"" ]
+ "params": [
+ "\"xslt/transform.xslt\""
+ ]
}
},
"operation": "TestIceSpider.TestApi.index"
@@ -146,4 +168,3 @@
"test-api.ice"
]
}
-
diff --git a/icespider/unittests/xslt/transformxml.xslt b/icespider/unittests/xslt/transformxml.xslt
new file mode 100644
index 0000000..42c0d8b
--- /dev/null
+++ b/icespider/unittests/xslt/transformxml.xslt
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output encoding="utf-8" method="xml" media-type="text/xml" indent="yes"/>
+ <xsl:template match="/SomeModel">
+ <M>
+ <xsl:attribute name="v">
+ <xsl:value-of select="value"/>
+ </xsl:attribute>
+ </M>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/icespider/xslt/xsltStreamSerializer.cpp b/icespider/xslt/xsltStreamSerializer.cpp
index 302ec21..6fb265c 100644
--- a/icespider/xslt/xsltStreamSerializer.cpp
+++ b/icespider/xslt/xsltStreamSerializer.cpp
@@ -61,7 +61,7 @@ namespace IceSpider {
if (!result) {
throw xmlpp::exception("Failed to apply XSL transform");
}
- const auto buf = std::unique_ptr<xmlOutputBuffer, decltype(&xmlOutputBufferClose)> {
+ auto buf = std::unique_ptr<xmlOutputBuffer, decltype(&xmlOutputBufferClose)> {
xmlOutputBufferCreateIO(xmlstrmwritecallback, xmlstrmclosecallback, &strm, nullptr),
&xmlOutputBufferClose};
if (xmlStrcmp(stylesheet->method, reinterpret_cast<const unsigned char *>("html")) == 0) {
@@ -69,8 +69,7 @@ namespace IceSpider {
buf.get(), result.get(), reinterpret_cast<const char *>(stylesheet->encoding), 0);
}
else {
- xmlNodeDumpOutput(buf.get(), result.get(), result->children, 0, 0,
- reinterpret_cast<const char *>(stylesheet->encoding));
+ xmlSaveFormatFileTo(buf.release(), result.get(), reinterpret_cast<const char *>(stylesheet->encoding), 0);
}
}
}