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())

Reply via email to