sw/qa/extras/ooxmlexport/ooxmlexport18.cxx | 22 +++++++++++++++++++++- sw/source/filter/ww8/docxattributeoutput.cxx | 6 ++++-- 2 files changed, 25 insertions(+), 3 deletions(-)
New commits: commit 3eb2871aefd01f2d0ce51848b7a6760b6adc9cb8 Author: Justin Luth <[email protected]> AuthorDate: Fri Feb 13 09:34:04 2026 -0500 Commit: Justin Luth <[email protected]> CommitDate: Sat Feb 14 20:34:36 2026 +0100 tdf#147724 docx export: don't export storeItemID if empty This patch is for the benefit of MS Word, which reports a document as corrupt if w:storeItemID="" It is kindof interesting, because it is not invalid if storeItemID is not provided. But if it is provided, then it must not be empty. make CppunitTest_sw_ooxmlexport18 CPPUNIT_TEST_NAME=testTdf147724 Change-Id: Iaa1de4b98e3470a3ab28fe48a46252060e70a257 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199354 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx index 47c3a69bdf1b..39294987712c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx @@ -608,8 +608,10 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf151912) assertXPath(pXmlDoc, "//w:sdt//w:sdtPr/w:id", "val", u"1802566103"); } -DECLARE_OOXMLEXPORT_TEST(testTdf147724, "tdf147724.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf147724) { + skipValidation(); // ERROR Attribute 'storeItemID' must appear on element 'w:dataBinding'. + createSwDoc("tdf147724.docx"); xmlDocUniquePtr pLayout = parseLayoutDump(); // Ensure we load field value from external XML correctly (it was "HERUNTERLADEN") @@ -619,6 +621,24 @@ DECLARE_OOXMLEXPORT_TEST(testTdf147724, "tdf147724.docx") // There 2 variants possible, both are acceptable OUString sFieldResult = getXPathContent(pLayout, "/root/page[1]/body/txt[2]"); CPPUNIT_ASSERT(sFieldResult == "Placeholder -> *HERUNTERLADEN*" || sFieldResult == "Placeholder -> *ABC*"); + + saveAndReload(TestFilter::DOCX); + pLayout = parseLayoutDump(); + + // Ensure we load field value from external XML correctly (it was "HERUNTERLADEN") + assertXPathContent(pLayout, "/root/page[1]/body/txt[1]", u"Placeholder -> *ABC*"); + + // This SDT has no storage id, it is not an error, but content can be taken from any suitable XML + // There 2 variants possible, both are acceptable + sFieldResult = getXPathContent(pLayout, "/root/page[1]/body/txt[2]"); + CPPUNIT_ASSERT(sFieldResult == "Placeholder -> *HERUNTERLADEN*" || sFieldResult == "Placeholder -> *ABC*"); + + xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); + assertXPath(pXmlDoc, "//w:p/w:sdt/w:sdtPr/w:dataBinding", 2); // two w:sdt's with w:dataBinding + assertXPath(pXmlDoc, "//w:p[1]/w:sdt/w:sdtPr/w:dataBinding", "storeItemID", + u"{4E8A9591-F074-446B-902F-511FF79C122F}"); + // empty storeItemID's must not be specified: MS Word considers those document corrupt + assertXPathNoAttribute(pXmlDoc, "//w:p[2]/w:sdt/w:sdtPr/w:dataBinding", "storeItemID"); } DECLARE_OOXMLEXPORT_TEST(testTdf130782, "chart.docx") diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 705f6cca86e5..47d96476146f 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2706,12 +2706,14 @@ void DocxAttributeOutput::WriteContentControlStart() m_pSerializer->singleElementNS(XML_w, XML_showingPlcHdr); } - if (!m_pContentControl->GetDataBindingPrefixMappings().isEmpty() || !m_pContentControl->GetDataBindingXpath().isEmpty() || !m_pContentControl->GetDataBindingStoreItemID().isEmpty()) + const OUString sID = m_pContentControl->GetDataBindingStoreItemID(); + if (!sID.isEmpty() || !m_pContentControl->GetDataBindingPrefixMappings().isEmpty() + || !m_pContentControl->GetDataBindingXpath().isEmpty()) { m_pSerializer->singleElementNS( XML_w, XML_dataBinding, FSNS(XML_w, XML_prefixMappings), m_pContentControl->GetDataBindingPrefixMappings(), FSNS(XML_w, XML_xpath), m_pContentControl->GetDataBindingXpath(), - FSNS(XML_w, XML_storeItemID), m_pContentControl->GetDataBindingStoreItemID()); + FSNS(XML_w, XML_storeItemID), sax_fastparser::UseIf(sID, !sID.isEmpty())); } if (m_pContentControl->GetTabIndex())
