Issue with LINQ inside XML Literals when generating XSD

39 views Asked by At

I'm creating an enumeration inside an XSD according to this answer. This is what I am aiming for, for reference:

<xs:simpleType name="color" final="restriction" >
  <xs:restriction base="xs:string">
    <xs:enumeration value="green" />
    <xs:enumeration value="red" />
    <xs:enumeration value="blue" />
  </xs:restriction>
</xs:simpleType>
<xs:element name="SomeElement">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Color" type="color" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

The enumeration comes from an IEnumerable(Of String) from which I thought to directly generate a series of these elements <xs:enumeration value="value1" />

Whenever I run my code, it creates xml correctly up to the point where LINQ is used, where it starts escaping > and < as &gt; and &lt;.

Output:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" id="Instruments">
  <xs:simpleType name="InstrumentName" final="restriction">
    <xs:restriction base="xs:string">&lt;xs:enumeration value="AccuvimDL"/&gt;&lt;xs:enumeration value="AccuvimDLSignal"/&gt;&lt;xs:enumeration value="AlignmentFormBase" ...

My code:

Private Sub saveXsd(names As IEnumerable(Of String), typeName As String, typeType As String)
    Dim xsd = <?xml version="1.0" encoding="utf-8"?>
              <xs:schema id="Instruments" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                  <xs:simpleType name=<%= typeType %> final="restriction">
                      <xs:restriction base="xs:string">
                          <%= From name In names
                              Select $"<xs:enumeration value=""{name}""/>" %>
                      </xs:restriction>
                  </xs:simpleType>
                  <xs:element name="SomeElement">
                      <xs:complexType>
                          <xs:sequence>
                              <xs:element name=<%= typeName %> type=<%= typeType %>/>
                          </xs:sequence>
                      </xs:complexType>
                  </xs:element>
              </xs:schema>
    xsd.Save("xsd.xsd")
End Function

I also tried with this syntax for the LINQ part

<%= From name In names Select <xs:enumeration value=<%= name %>/> %>

but the <xs: namespace is not recognized because it is no longer part of the xml literal and can't compile.

I want to know if this should be possible. I think the xml literal feature of VB.Net is cool and I hope to be able to use it.

Edit:

Writing the question must have knocked something loose in my head. I found a solution, though not ideal.

The second LINQ method will work if I add a namespace

<%= From name In names 
    Select <xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value=<%= name %>/> %>

However I end up with the namespace in each element. I guess it's ok for an xsd...

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" id="Instruments">
  <xs:simpleType name="InstrumentName" final="restriction">
    <xs:restriction base="xs:string">
      <xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value="AccuvimDL" />
      <xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value="AccuvimDLSignal" />
      <xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value="AlignmentFormBase" />
      ...

Still open to other suggestions

1

There are 1 answers

1
Sprotty On BEST ANSWER

Sorry wasn't familiar with the VB.Net XML literals, so I was intrigued.

Looks like you need the import

Imports <xmlns:xs="http://www.w3.org/2001/XMLSchema">

Module Module1

    Sub Main()
        Dim xsd = <?xml version="1.0" encoding="utf-8"?>
                  <xs:schema id="Instruments" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                      <xs:simpleType name=<%= "test" %> final="restriction">
                          <xs:restriction base="xs:string">
                              <%= From name In names
                                  Select <xs:enumeration value=" {name}"/> %>
                          </xs:restriction>
                      </xs:simpleType>
                  </xs:schema>
        xsd.Save("xsd.xsd")
    End Sub

End Module