summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorBayram Çiçek <bayram.cicek@collabora.com>2025-09-14 01:16:07 +0300
committerCaolán McNamara <caolan.mcnamara@collabora.com>2025-09-15 09:40:36 +0200
commit2034abc1bb10a69d9bc4d098f4cb82d63e6f73bf (patch)
tree33d63bd104d347bd5703c2973b4efd97608979f3 /sc
parent8c5fd04f0bb5bf75192d1c4ddd4d80f608796d7c (diff)
tdf#167689: sc: export x15 namespace for xl/connections.xml
- add support for x15 namespace. - add a unittest. - add support for <x15:connection> and <x15:rangePr> elements. - support model and sourceName attributes. <extLst> <ext xmlns:x15="..." > <x15:connection id="..." model="..."> <x15:rangePr sourceName="..."/> </x15:connection> </ext> </extLst> Signed-off-by: Bayram Çiçek <bayram.cicek@collabora.com> Change-Id: I3b3e380ddd07f251b23333fe9d3959961dd5c19c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190924 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/unit/data/xlsx/tdf167689_x15_namespace.xlsxbin0 -> 174497 bytes
-rw-r--r--sc/qa/unit/subsequent_export_test4.cxx22
-rw-r--r--sc/source/filter/excel/excdoc.cxx60
-rw-r--r--sc/source/filter/inc/connectionsbuffer.hxx10
-rw-r--r--sc/source/filter/oox/connectionsbuffer.cxx14
-rw-r--r--sc/source/filter/oox/connectionsfragment.cxx17
6 files changed, 110 insertions, 13 deletions
diff --git a/sc/qa/unit/data/xlsx/tdf167689_x15_namespace.xlsx b/sc/qa/unit/data/xlsx/tdf167689_x15_namespace.xlsx
new file mode 100644
index 000000000000..afd81dd2edb8
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf167689_x15_namespace.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx
index e7588ad5a41c..c403a68d3a05 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -2226,6 +2226,28 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166712)
assertXPath(pConn, "/x:connections/x:connection/x:olapPr", 0);
}
+CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf167689_x15_namespace)
+{
+ createScDoc("xlsx/tdf167689_x15_namespace.xlsx");
+
+ save(u"Calc Office Open XML"_ustr);
+
+ xmlDocUniquePtr pConn = parseExport(u"xl/connections.xml"_ustr);
+ CPPUNIT_ASSERT(pConn);
+
+ // test if <ext> has xmlns:x15 namespace.
+ assertXPathNSDef(pConn, "/x:connections/x:connection[3]/x:extLst/x:ext", "x15",
+ "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
+
+ // test id attribute of <x15:connection>
+ assertXPath(pConn, "/x:connections/x:connection[3]/x:extLst/x:ext/x15:connection", "id",
+ u"Tabelle1");
+
+ // test sourceName attribute of <x15:rangePr>
+ assertXPath(pConn, "/x:connections/x:connection[3]/x:extLst/x:ext/x15:connection/x15:rangePr",
+ "sourceName", u"_xlcn.LinkedTable_Tabelle1");
+}
+
CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166939)
{
// Given a document with a column autostyle name equal to "a" (it could be any single-character
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
index 38ab0d78b831..0d0c6655aaab 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -1229,21 +1229,55 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
// put <extLst>, it has no attributes
rStrm.GetCurrentStream()->startElement(XML_extLst);
- // export uri attribute of <ext> element
+ // export <ext> with uri attribute and xmlns:x15 namespace.
for (auto& uriValue : rModel.mxExtensionList->vExtension)
{
- // export <ext> with uri attribute.
- rStrm.GetCurrentStream()->startElement(XML_ext, XML_uri, uriValue);
-
- /*
- TODO: export child elements of <ext>. We should export "any element in any namespace", which seems challenging.
-
- <extLst>
- <ext>
- (Any element in any namespace)
- </ext>
- </extLst>
- */
+ rStrm.GetCurrentStream()->startElement(XML_ext, FSNS(XML_xmlns, XML_x15),
+ rStrm.getNamespaceURL(OOX_NS(x15)),
+ XML_uri, uriValue);
+
+ /*
+ Export child elements of <ext> here.
+ We should export "any element in any namespace" when it is needed.
+
+ <extLst>
+ <ext>
+ (Any element in any namespace)
+ </ext>
+ </extLst>
+ */
+
+ // export <x15:connection> if not empty
+ aSeqs = rModel.mxExtensionList->maXFifteenConnectionSequenceAny;
+ if (aSeqs.hasElements())
+ {
+ rtl::Reference<sax_fastparser::FastAttributeList>
+ pAttrListXFifteenConnection
+ = sax_fastparser::FastSerializerHelper::createAttrList();
+
+ addElemensToAttrList(pAttrListXFifteenConnection, aSeqs);
+
+ rStrm.GetCurrentStream()->startElement(FSNS(XML_x15, XML_connection),
+ pAttrListXFifteenConnection);
+
+ // export <x15:rangePr> if not empty
+ aSeqs = rModel.mxExtensionList->maXFifteenRangePrSequenceAny;
+ if (aSeqs.hasElements())
+ {
+ rtl::Reference<sax_fastparser::FastAttributeList>
+ pAttrListXFifteenRangePr
+ = sax_fastparser::FastSerializerHelper::createAttrList();
+
+ addElemensToAttrList(pAttrListXFifteenRangePr, aSeqs);
+
+ // put <x15:rangePr />
+ rStrm.GetCurrentStream()->singleElement(FSNS(XML_x15, XML_rangePr),
+ pAttrListXFifteenRangePr);
+ }
+
+ // put </x15:connection>
+ rStrm.GetCurrentStream()->endElement(FSNS(XML_x15, XML_connection));
+ }
// put </ext>
rStrm.GetCurrentStream()->endElement(XML_ext);
diff --git a/sc/source/filter/inc/connectionsbuffer.hxx b/sc/source/filter/inc/connectionsbuffer.hxx
index 5f3fb3ac734f..b5742c3c2bff 100644
--- a/sc/source/filter/inc/connectionsbuffer.hxx
+++ b/sc/source/filter/inc/connectionsbuffer.hxx
@@ -100,6 +100,12 @@ struct ExtensionListModel
// <ext> has only one attribute:
// - uri (A token to identify version and application information for the particular extension)
std::vector<OUString> vExtension; // holds uri (URI) attribute of <ext> (Extension) element.
+
+ // <x15:connection> attributes. A child element of <ext>.
+ css::uno::Sequence<css::uno::Any> maXFifteenConnectionSequenceAny;
+ // <x15:rangePr> attributes. A child element of <x15:connection>.
+ css::uno::Sequence<css::uno::Any> maXFifteenRangePrSequenceAny;
+
};
/** Common properties of an external data connection. */
@@ -177,6 +183,10 @@ public:
void importExtensionList();
/** Imports extensions to the standard SpreadsheetML feature set, from the ext element. */
void importExtension(const AttributeList& rAttribs);
+ /** Imports <x15:connection> element. */
+ void importXFifteenConnection(const AttributeList& rAttribs);
+ /** Imports <x15:rangePr> element. */
+ void importXFifteenRangePr(const AttributeList& rAttribs);
/** Imports connection settings from the CONNECTION record. */
void importConnection( SequenceInputStream& rStrm );
diff --git a/sc/source/filter/oox/connectionsbuffer.cxx b/sc/source/filter/oox/connectionsbuffer.cxx
index 6da344c4ceb3..2a18b1b08028 100644
--- a/sc/source/filter/oox/connectionsbuffer.cxx
+++ b/sc/source/filter/oox/connectionsbuffer.cxx
@@ -321,6 +321,20 @@ void Connection::importExtension(const AttributeList& rAttribs)
maModel.mxExtensionList->vExtension.push_back(sUri);
}
+void Connection::importXFifteenConnection(const AttributeList& rAttribs)
+{
+ if (auto xFastAttributeList = rAttribs.getFastAttributeList())
+ maModel.mxExtensionList->maXFifteenConnectionSequenceAny
+ = getSequenceOfAny(xFastAttributeList);
+}
+
+void Connection::importXFifteenRangePr(const AttributeList& rAttribs)
+{
+ if (auto xFastAttributeList = rAttribs.getFastAttributeList())
+ maModel.mxExtensionList->maXFifteenRangePrSequenceAny
+ = getSequenceOfAny(xFastAttributeList);
+}
+
css::uno::Sequence<css::uno::Any> Connection::getSequenceOfAny(
const css::uno::Reference<css::xml::sax::XFastAttributeList>& xFastAttributeList)
{
diff --git a/sc/source/filter/oox/connectionsfragment.cxx b/sc/source/filter/oox/connectionsfragment.cxx
index 68b30587c547..cefc55e43350 100644
--- a/sc/source/filter/oox/connectionsfragment.cxx
+++ b/sc/source/filter/oox/connectionsfragment.cxx
@@ -115,6 +115,23 @@ ContextHandlerRef ConnectionContext::onCreateContext( sal_Int32 nElement, const
return this;
}
break;
+
+ case XLS_TOKEN(ext):
+ if (nElement == X15_TOKEN(connection))
+ {
+ // imports <x15:connection> element
+ mrConnection.importXFifteenConnection(rAttribs);
+ return this;
+ }
+ break;
+ case X15_TOKEN(connection):
+ if (nElement == X15_TOKEN(rangePr))
+ {
+ // imports <x15:rangePr> element
+ mrConnection.importXFifteenRangePr(rAttribs);
+ return this;
+ }
+ break;
}
return nullptr;
}