4

I am working with Linq to Xml to manipulate openXml documents. More precisely I am trying to read and write to the documents custom properties. I am currently having a problem appending a prefix onto an XElement. My code looks like:

Dim main as XNameSpace = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"

Dim vt as XNameSpace = "http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes"

Dim props as XElement = cXDoc.Element(main + "Properties"
        props.Add(New XElement(main + "property"), _
                               New XAttribute("fmtid", formatId), _
                               New XAttribute("pid", pid + 1), _
                               New XAttribute("name", "test"), _
                                    New XElement(vt + "lpwstr", "test value")) _
                 )

The Xml contained in props before the add is :

<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" />

The Xml after the props.add method() call is:

   <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  <property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="test">
    <lpwstr xmlns="http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes">test value</lpwstr>
  </property>
</Properties>

Within the property element I should be getting

<vt:lpwstr>test value</vt:lpwstr> 

but just can't get this to happen. I don't want the xmlns attribute for this element here either. I think I somehow need to get the map the vt XNameSpace back to the namespace declaration in the root element "Properties". Does anyone have any suggestions?

0

2 Answers 2

2

At some place in the XElement, you'll need the prefix defined. Here's how to do it by putting the vt xmlns at the top, by adding it as an XAttribute: New XAttribute(XNamespace.Xmlns + "vt", "http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes")

Dim main As XNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
Dim vt As XNamespace = "http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes"
Dim formatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
Dim pid = "2"
Dim props As New XElement(main + "Properties", New XAttribute(XNamespace.Xmlns + "vt", "http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes"))
props.Add(New XElement(main + "property"), _
                       New XAttribute("fmtid", formatId), _
                       New XAttribute("pid", pid + 1), _
                       New XAttribute("name", "test"), _
                            New XElement(vt + "lpwstr", "test value"))

XML Literals and global namespaces may be easier, but you'll still need vt listed in the XML at a parent level. Here's an XML Literals example (remember to put both Imports statements at the top of the class/module, above everything else):

Imports <xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties">
Imports <xmlns:vt="http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes">
    Sub GetXml()
        Dim formatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
        Dim pid = "2"
        Dim props2 = <Properties>
                         <property fmtid=<%= formatId %> pid=<%= pid + 1 %> name="test">
                             <vt:lpwstr>test value</vt:lpwstr>
                         </property>
                     </Properties>
        MsgBox(props2.ToString)
    End Sub
Sign up to request clarification or add additional context in comments.

Comments

1

The way I have found to control where the namepaces are declared is to use Xml Literals. I also have to recreate the document from scratch and copy any existing information from the old document into my newly created document which isn't ideal. There is also a bug in the example above which is enough to get any of the Office Documents to corrupt after running the code.

Dim vt as XNameSpace = "http://schemas.openxmlformats.org/officeDocument2006/docPropsVTypes"

Should read

Dim vt as XNameSpace = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"

1 Comment

Welcome to StackOverflow Andrew! It is OK for you to answer your own question, but when you're just providing more information, it would be better to edit your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.