/ / VB.NET Rozwiązywanie aliasów XML ze schematu wbudowanego - xml, vb.net

VB.NET Rozwiązywanie aliasów XML ze schematu inline - xml, vb.net

Korzystam z usługi sieciowej, która zapewnia XMLdane z wbudowanym schematem. Wygląda jak wyjście XML z Microsoft ADO. Schemat zawiera pełne nazwy atrybutów, podczas gdy same dane zawierają tylko aliasy.

Przykładowy plik XML:

<?xml version="1.0" encoding="utf-8"?>
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly">
<s:AttributeType name="c4" rs:name="FULLNAME" rs:number="5" />
<s:AttributeType name="c5" rs:name="FIRSTNAME" rs:number="6" />
<s:AttributeType name="c6" rs:name="MIDDLENAME" rs:number="7" />
<s:AttributeType name="c7" rs:name="LASTNAME" rs:number="8" />
<s:AttributeType name="c8" rs:name="ADDRESSLINE1" rs:number="9" />
<s:AttributeType name="c9" rs:name="ADDRESSLINE2" rs:number="10" />
<s:AttributeType name="c10" rs:name="CITY" rs:number="11" />
<s:AttributeType name="c11" rs:name="POSTALCODE" rs:number="12" />
<s:AttributeType name="c12" rs:name="STATE" rs:number="13" />
</s:ElementType>
</s:Schema>
<rs:data>
<z:row c4="Jane Frickin Doe"
c5="Jane"
c6="Frickin"
c7="Doe"
c8="1234 Fifth Ave"
c9=""
c10="Anywhere"
c11="98765"
c12="US"/>
</rs:data>
</xml>

Mogę to dobrze przeciągnąć do XDocument i iterować przez rekordy, używając:

For Each person In personRecs...<z:row>
Dim firstName as String = person.@c5
Next

Stwarza to jednak problemy, ponieważ kolejność pól może zmieniać się dowolnie w miarę dodawania lub usuwania pól (imię może brzmieć @c6, jeśli wcześniej dodano inne pole). person.@FIRSTNAME zamiast?

Odpowiedzi:

2 dla odpowiedzi № 1

Ryzykując stwierdzenie oczywistego - i jakodla mnie to odlot z przeszłości :) - ponieważ jest to rzeczywisty plik xml zestawu rekordów ADO, możesz go po prostu wepchnąć do zestawu rekordów ADO i na pewno będziesz miał dostęp do nazwanych pól.

Potrzebujesz odniesienia do .net „ADODB” w projekcie. A potem możesz mieć następujące:

    string strInputXML;
strInputXML = string.Concat(
"<?xml version="1.0" encoding="utf-8"?>",
"<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" ",
"xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" ",
"xmlns:rs="urn:schemas-microsoft-com:rowset" ",
"xmlns:z="#RowsetSchema">",
"<s:Schema id="RowsetSchema">",
"    <s:ElementType name="row" content="eltOnly">",
"   <s:AttributeType name="c4" rs:name="FULLNAME" rs:number="5" />",
"   <s:AttributeType name="c5" rs:name="FIRSTNAME" rs:number="6" />",
"   <s:AttributeType name="c6" rs:name="MIDDLENAME" rs:number="7" />",
"   <s:AttributeType name="c7" rs:name="LASTNAME" rs:number="8" />",
"   <s:AttributeType name="c8" rs:name="ADDRESSLINE1" rs:number="9" />",
"   <s:AttributeType name="c9" rs:name="ADDRESSLINE2" rs:number="10" />",
"   <s:AttributeType name="c10" rs:name="CITY" rs:number="11" />",
"   <s:AttributeType name="c11" rs:name="POSTALCODE" rs:number="12" />",
"   <s:AttributeType name="c12" rs:name="STATE" rs:number="13" />",
"    </s:ElementType>",
"</s:Schema>",
"<rs:data>",
"<z:row c4="Jane Frickin Doe"",
" c5="Jane"",
" c6="Frickin"",
" c7="Doe"",
" c8="1234 Fifth Ave"",
" c9=""",
" c10="Anywhere"",
" c11="98765"",
" c12="US"/>",
"</rs:data>",
"</xml>"
);
//--- interestingly, you have to drop the xml declaration
// I"ll be lazy and cut it as a string for this example
strInputXML = strInputXML.Replace("<?xml version="1.0" encoding="utf-8"?>", "");

//--- And we can load an actual ADODB.recordset with it, for named field access
ADODB.Stream objADOStream = new ADODB.Stream();
objADOStream.Open();
objADOStream.WriteText(strInputXML);
objADOStream.Position = 0;
ADODB.Recordset objRS = new ADODB.Recordset();
objRS.Open(objADOStream);

Console.WriteLine (objRS.Fields["FULLNAME"].Value);

0 dla odpowiedzi nr 2

Czy możesz uzyskać dostęp do schematu programowo? Oznacza to, że przeczytaj go tak, jak każdą inną część dokumentu XML?

Czytam w schemacie i buduję a Dictionary<string, string> mapowanie nazw pól (FIRSTNAME, itp.) na znaczniki (C4-C12) i wyszukiwanie nazwy znacznika według nazwy pola.

Mój VB jest zardzewiały, ale mógłbym podać przykładowy kod w C#, jeśli chcesz.


0 dla odpowiedzi № 3

Możesz uzyskać nazwę atrybutu dla FIRSTNAME w ten sposób:

Dim firstNameAttributeName As String = (
From attr
In doc...<s:AttributeType>
Where attr.@rs:name = "FIRSTNAME"
Select attr.@name
).First()

(Gdzie doc czy Twój XDocument object) Następnie możesz uzyskać wartość tego atrybutu dla dowolnego danego elementu w ten sposób:

Dim personName As String = person.Attribute(firstNameAttributeName).Value

(Gdzie person jest XElement obiekt) Wykonanie tego wymaga oczywiście następujących czynności: Imports:

Imports <xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882">
Imports <xmlns:rs="urn:schemas-microsoft-com:rowset">
Imports <xmlns:z="#RowsetSchema">