Resolved Wanting to add to XDocument to make more than one "entry" on a single write...

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
Wanting to add to XDocument to make more than one "entry" on a single write...

I think I am missing something here, not sure I understand how to do this.

I have some snippit code I massaged and got working fine, but when I add line ??? I get:

Severity Code Description Project File Line Suppression State
Error BC30452 Operator '+' is not defined for types 'XDocument' and 'XDeclaration'. vb-forms-dotnet 3.5 - xml 1 F:\VisualStudio\2015\vb-forms-dotnet 3.5 - xml 1\vb-forms-dotnet 3.5 - xml 1\Form1.vb 308 Active


I would appreciate insight on how to add another element with one write using LINQ, I had a hard enough time finding code that works just to write one element.

Line 6 is the line I added and then got the posted error.:
      ' used in original code, not used here  Dim empNM As XNamespace = "urn:lst-emp:emp"

        Dim xDoc As New XDocument(New XDeclaration("1.0", "UTF-16", Nothing), New XElement("Employees", New XElement("Employee", New XComment("Only 3 elements for demo purposes"), New XElement("EmpId", "5"), New XElement("Name", "Kimmy"), New XElement("Sex", "Female"))))

        ' try to add another element
        xDoc = xDoc + (New XDeclaration("1.0", "UTF-16", Nothing), New XElement("Employees", New XElement("Employee", New XComment("Only 3 elements for demo purposes"), New XElement("EmpId", "5"), New XElement("Name", "Kimmy"), New XElement("Sex", "Female"))))

        Dim sw As New System.IO.StringWriter()
        Dim xWrite As XmlWriter = XmlWriter.Create(sw)
        xDoc.Save(xWrite)
        xWrite.Close()

        ' Save to Disk
        xDoc.Save("F:\VisualStudio\DevResources\LINQxml-1.xml")
        Console.WriteLine("Saved")
 
Last edited:

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
I got this edited and resolved errors during edit, but generated run time error:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.Linq.dll

Additional information: This operation would create an incorrectly structured document.


Line 2 throws the run time error:
    ' try to add another element
        xDoc.Add(New XElement("Employees", New XElement("Employee", New XComment("This is my own comment"), New XElement("EmpId", "67"), New XElement("Name", "Shazam"), New XElement("Sex", "Male"))))
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
Here is what I am getting without adding line 6 in my original post, a well formed XML


VB.NET:
<?xml version="1.0" encoding="utf-16"?>
<Employees>
  <Employee>
    <!--Only 3 elements for demo purposes-->
    <EmpId>5</EmpId>
    <Name>Kimmy</Name>
    <Sex>Female</Sex>
  </Employee>
</Employees>



This is what I was hoping to achieve with the addition of line 2 in the above post.

VB.NET:
<?xml version="1.0" encoding="utf-16"?>
<Employees>
  <Employee>
    <!--Only 3 elements for demo purposes-->
    <EmpId>5</EmpId>
    <Name>Kimmy</Name>
    <Sex>Female</Sex>
  </Employee>
  <Employee>
    <!--This is my own comment-->
    <EmpId>67</EmpId>
    <Name>Shazam</Name>
    <Sex>Male</Sex>
  </Employee>
</Employees>

By the way, thank you for your time.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,603
Location
Norway
Programming Experience
10+
These help pages should be useful: XML - Visual Basic
You'll see simpler ways to create, access and modify xml documents with literals. Browse through them to get a feel for working with xml using these tools.
Typically you create a new document and save it (or send it somewhere). Later load it (or get from womewhere), access some elements to modify them or add/remove them, then save again.
As remark in XDocument help page says, you don't typically create a document like you are trying, but instead build from XElement (with or without using xml literals).
In the case where you have the first document in post 4 and want to add another Employee you typically load the document, select the root (or whatever element(s) you want to manipulate) and add another XElement to it, then save.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,603
Location
Norway
Programming Experience
10+
A quick sample how I would do this:
VB.NET:
Dim id = 5, name = "Kimmy", sex = "Female"
Dim element = <Employees>
                  <Employee>
                      <EmpId><%= id %></EmpId>
                      <Name><%= name %></Name>
                      <Sex><%= sex %></Sex>
                  </Employee>
              </Employees>
Dim filename = "sample.xml"
element.Save(filename)
Note the xml is pure structural, I've used variables for the actual data.
The xml declaration with encoding is automatically added. Standard encoding is Utf-8. If I for some reason wanted Utf-16 (Unicode) I would save like this:
VB.NET:
Using writer As New IO.StreamWriter(filename, False, System.Text.Encoding.Unicode)
    element.Save(writer)
End Using
Loading, adding a new element to root, saving again:
VB.NET:
id = 67 : name = "Shazam" : sex = "Male"
Dim doc = XDocument.Load(filename)
doc.Root.Add(<Employee>
                 <EmpId><%= id %></EmpId>
                 <Name><%= name %></Name>
                 <Sex><%= sex %></Sex>
             </Employee>)
doc.Save(filename)
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
That worked a treat!

The only thing I couldnt figure out was how to add a comment.

Added elements to exisiting XML:
<?xml version="1.0" encoding="utf-16"?>
<Employees>
  <Employee>
    <!--Only 3 elements for demo purposes-->
    <EmpId>5</EmpId>
    <Name>Kimmy</Name>
    <Sex>Female</Sex>
  </Employee>
  <Employee>
    <EmpId>67</EmpId>
    <Name>Shazam</Name>
    <Sex>Male</Sex>
  </Employee>
</Employees>


using this code:
tweaked code:
        Dim id As String = "67"
        Dim Name As String = "Shazam"
        Dim sex As String = "Male"
        'Dim comment As String = "This is a new comment"
        Dim filename As String = "F:\VisualStudio\DevResources\LINQxml-1.xml"

        Dim doc = XDocument.Load(filename)
        doc.Root.Add(<Employee>
                         <EmpId><%= id %></EmpId>
                         <Name><%= Name %></Name>
                         <Sex><%= sex %></Sex>
                     </Employee>)
        doc.Save(filename)
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
When I try to add a comment, I get this as the output:
VB.NET:
  <Employee>
    <!-- <%= comment %> -->
    <EmpId>99</EmpId>
    <Name>Balto</Name>
    <Sex>Male</Sex>
  </Employee>
</Employees>

here is where I added the comment line, evidently I need to use an escape sequence??

VB.NET:
        Dim id As String = "99"
        Dim Name As String = "Balto"
        Dim sex As String = "Male"
        Dim comment As String = "This is a new comment"
        Dim filename As String = "F:\VisualStudio\DevResources\LINQxml-1.xml"

        Dim doc = XDocument.Load(filename)
        doc.Root.Add(<Employee>
                         <!-- <%= comment %> -->
                         <EmpId><%= id %></EmpId>
                         <Name><%= Name %></Name>
                         <Sex><%= sex %></Sex>
                     </Employee>)
        doc.Save(filename)
 
Last edited:

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,603
Location
Norway
Programming Experience
10+
Which means you can do this:
VB.NET:
Dim element = <Employees>
                  <Employee>
                      <!-- comment -->
                      <EmpId><%= id %></EmpId>
                      <Name><%= name %></Name>
                      <Sex><%= sex %></Sex>
                  </Employee>
              </Employees>
Dynamic content (see remarks) means using XComment element, for example:
VB.NET:
element...<Employee>.First().AddFirst(New XComment("dynamic comment"))
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
I tried that, just put it in the code as raw "<!-- This is a comment -->", but I would like to replace "This is a comment" with a string but I cant figure out how to do that
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,603
Location
Norway
Programming Experience
10+
I already showed you how to add comment with "dynamic content", that string is VB code that can be replaced with a variable.
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
Okay, I had to work with it to understand it... you pointed me in the right direction!!

THANK YOU!


The following code...:
        Dim id As String = "99"
        Dim Name As String = "Balto"
        Dim sex As String = "Male"
        Dim commenttxt As String = "<-- This is a new comment -->"
        Dim filename As String = "F:\VisualStudio\DevResources\LINQxml-1.xml"
        Dim com As XComment = <!-- This is a custom comment -->

        Dim doc = XDocument.Load(filename)
        doc.Root.Add(<Employee>
                         <%= com %>
                         <EmpId><%= id %></EmpId>
                         <Name><%= Name %></Name>
                         <Sex><%= sex %></Sex>
                     </Employee>)
        doc.Save(filename)


... yielded the follow results:
  <Employee>
    <!-- This is a custom comment -->
    <EmpId>99</EmpId>
    <Name>Balto</Name>
    <Sex>Male</Sex>
  </Employee>
 

Program4Food

Member
Joined
Dec 6, 2021
Messages
16
Programming Experience
5-10
I appreciate you all's patience with me. I admit I am not very smart and maybe my brain is kinda slow
(between ADHD and PTSS).

Making code work and learning from it gives me a great sense of accomplishment.
It really does mean a lot to me! Thank you!
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,603
Location
Norway
Programming Experience
10+
Dim com As XComment = <!-- This is a custom comment -->
That is not a "custom" comment as such, it just a standard xml literal with static text.
This is a comment where you can substitute the string with any string variable:
VB.NET:
Dim com As New XComment("This is a custom comment")
<%= com %>
Nice, didn't know you could do that.
 
Top Bottom