Powszechność dziwnych praktyk w XML

4

Przykład ilustrujący to, o czym chcę pisać.

Kod produkcyjny w XML:

<key>impossible_difficulty_enabled</key>
<true/>

(pochodzi on z plików pewnej gry kupionej przeze mnie na Steamie)

Jak widzę tego rodzaju kod w XMLu to zaczynam zgrzytać zębami.

Ale kiedy to przeczytałem, zauważyłem u siebie, że nie czuję już zdziwienia, kiedy to czytam. To, że XMLe tak wyglądają, traktuję już jako normę. Czuję raczej irytację, choć w zasadzie nie powinienem, bo to przecież nie mój kod i ja z nim pracować nie muszę.

Na podstawie mojego niezbyt wielkiego doświadczenia wydaje mi się, że kod w XMLu w ten sposób wygląda bardzo często.

Ale to właśnie w XMLu. W na przykład JSONie już raczej by się czegoś takiego nie spotkało. Nikt nie napisałby chyba czegoś takiego:

{
    "key": "impossible_difficulty_enabled",
    "true": {}
}

Analogiczny zapis w JSONie wyglądałby raczej tak:

{
    "impossible_difficulty_enabled": true
}

Czy XML jest jakiś upośledzony?

Mimo wszystkich dziwactw XMLa da się w nim przecież pisać nawet prościej, niż w JSONie:

<impossible_difficulty_enabled/>

ALbo chociaż:

<impossible_difficulty_enabled>
    <true/>
</impossible_difficulty_enabled>

XML jest mocno przekombinowany, to fakt. Ale przekombinowanie samego XMLa to jedno, natomiast praktyki przekombinowujące kod w XMLu to drugie. Jeśli już ktoś pisze w XMLu, to czemu nie będzie chociaż tego pisał tak, żeby to miało ręce i nogi? Czemu do dziwactw XMLa musi dodawać jeszcze dziwactwa własne?

  1. Czy mam rację, czy mi się tylko niesłusznie wydaje, że XMLe bardzo często wyglądają w ten sposób, jaki podałem w przykładzie na początku mojego posta?
  2. Jeśli tak, to z czego to wynika? Może jest jakiś istotny powód, dla którego ludzie tak piszą XMLe, tyle że ja go nie znam?
0

a dlaczemu nie

<impossible_difficulty_enabled=true/>

albo

<key>impossible_difficulty_enabled</key>
<value>true</value>

żeby to jakoś sensownie wyglądało

btw z taką postacią, jak podałeś jeszcze się nie spotkałem

3

Dobrze, ale po co w ogóle zaglądasz do jakichś losowych xmli na świecie? :P

Może jakaś nowoczesna biblioteka do serializacji tak serializuje, kto wie.

3

Jako zagorzały przeciwnik XMLa nigdy nie myślałem o tym problemie. IMO to wynika z tego, że XML nie mapuje się na nic, co jest reprezentowane jako struktury danych w językach programowania. JSON jest trywialny do serializacji/parsowania (poza liczbami, ale to dużo mniejszy problem) w dowolnym języku programowania. Z drugiej strony mamy XMLa w którym możemy przedstawić to samo za pomocą różnych konceptów. Mamy node vs attribute, <key>value</key> vs <node><key>key</key><value>value</value></node> nie wiemy jak przedstawiać kolekcję, nie wiemy, czy subnody w danym nodzie to klucze w mapie/strukturze czy cholera wie co.

Pewnie to wygląda tak, że ktoś coś kiedyś pokracznie przedstawi, bo nie ma jasnej wykładni/oczywistego sposobu jak rozwiązać dany problem. Po tym przychodzi ktoś inny i zaczyna kopiować to co zobaczył i tak się tworzą różne dialekty. Np. ja pracowałem w takim projekcie, gdzie wszystko było przedstawiane jako atrybuty. Nody nie zawierały wartości innych, niż inne nody. Co niestety rodziło takie patologie jak ad-hoc struktury danych jak np attrValue="comma,separated,list"

3

XML to po prostu nie jest i nie był język/format stworzony do przechowywania, wysyłania danych i konfiguracji.

To jest po prostu markup langauge, czyli język do oznacza elementów w tekście, tak samo z resztą jak np html i markdown.

Stosowało się w nim konfigurację powiedziałbym z braku laku, ale teraz mamy alternatywy, np yaml. JSON moim skromnym zdaniem to też średni kandydat na trzymanie konfiguracji.

3

Czemu do dziwactw XMLa musi dodawać jeszcze dziwactwa własne?

Zapewne z tego samego powodu, dla którego w 2020+ wybrano XML jako bazowy format zapisu konfiguracji. Głupota, lenistwo, terminy.

Może było już coś gotowego w bibliotece, a skoro XML to kupa, to po co się wysilać i robić schemat z rigczem.

2
abrakadaber napisał(a):

a dlaczemu nie

<impossible_difficulty_enabled=true/>

A to jest w ogóle poprawny XML? Jeśli jest, to chyba byłoby OK, ale to nowość dla mnie

albo

<key>impossible_difficulty_enabled</key>
<value>true</value>

żeby to jakoś sensownie wyglądało

No właśnie tego formatu kompletnie nie rozumiem.

Czemu

<key>nazwa_klucza</key>
<value>wartość</value>

Skoro można

<nazwa_klucza>
    wartość
</nazwa_klucza>

albo

<nazwa_klucza wartość="" />

albo

<nazwa_klucza>
    <wartość />
</nazwa_klucza>

Tagi <key> oraz <value> nie wnoszą żadnej wartości dodanej, to tylko szum.

slsy napisał(a):

Jako zagorzały przeciwnik XMLa nigdy nie myślałem o tym problemie. IMO to wynika z tego, że XML nie mapuje się na nic, co jest reprezentowane jako struktury danych w językach programowania. JSON jest trywialny do serializacji/parsowania (poza liczbami, ale to dużo mniejszy problem) w dowolnym języku programowania. Z drugiej strony mamy XMLa w którym możemy przedstawić to samo za pomocą różnych konceptów. Mamy node vs attribute, <key>value</key> vs <node><key>key</key><value>value</value></node> nie wiemy jak przedstawiać kolekcję, nie wiemy, czy subnody w danym nodzie to klucze w mapie/strukturze czy cholera wie co.

JSON jest pod tym względem lepszy, ale nie do końca się zgodzę, że taki trywialny.

Po części ten problem występuje także w JSON. Bo jak masz coś takiego:

{
    "blablabla": 1234,
    "pleplepleple": 5678
}

to nie wiesz, czy została tak zserializowana klasa posiadająca dwa pola typu int, czy też słownik mapujący stringi na inty.

Ale mimo to w JSONie chyba raczej nie występuje taka (moim zdaniem) patologia, jak odróżnianie słowników od obiektów poprzez serializację ich w ten sposób:

[
    {
        "key": "blablabla",
        "value": 1234
    },
    {
        "key": "pleplepleple",
        "value": 5678
    }
]

Zakłada się raczej, że wprowadzanie pól o nazwie key i value to tylko szum, zaciemniający znaczenie tego, co się chce serializować. Bo i zresztą wprowadzanie pól o nazwie key czy value nie pomaga w ujednoznacznieniu formatu, ostatecznie może być klasa, która ma takie pola. Nie można zatem zdeserializować JSONa bez wcześniejszej wiedzy, co w tym JSONie może wystąpić i jak się to przekłada na struktury języka programowania.

Tak samo jest z XMLem. Chociaż ma dużo więcej niejednoznaczności niż JSON, podstawowy problem pozostaje ten sam.

slsy napisał(a):

bo nie ma jasnej wykładni/oczywistego sposobu jak rozwiązać dany problem. Po tym przychodzi ktoś inny i zaczyna kopiować to co zobaczył i tak się tworzą różne dialekty.

No więc czemu nie iść drogą najprostszą z możliwych?

Na przykład:

Obiekty serializować tak:

<nazwa_pola>
    wartość_pola
</nazwa_pola
<nazwa_drugiego_pola>
    wartość_drugiego_pola
</nazwa_drugiego_pola>

Słowniki tak:

<klucz>
    wartość
</klucz>
<drugi_klucz>
    wartość
</drugi_klucz>

Listy tak:

<wartość_pierwsza/>
<wartość_druga/>
<wartość_trzecia/>

Itp?

(chyba, że - teraz mi wpadło do głowy - może w XML musi być z góry znana skończona liczba tagów, określona w schema, więc nie można kluczy słowników czy elementów list dawać jako tagów? To by tłumaczyło powszechność tagów typu <key>, <value>, <element> )

3

Próbujesz robić revers enginerig na podstawie tego, co jest w XMLach? Musisz mieć za dużo czasu chyba. Próbujesz oceniać coś od d u p y strony. XML to jest tylko format zapisu, nic ponadto, to co robi z nim programista to tylko wina programisty, a nie samego formatu.
Problem pewnie wziął się bardziej ze słabości parserów tegoż XML gdzie to wszystko jest "nodem" a nie z założeń samego XMLa.

0

Takie formaty jak XML, JSON, CSV itp. lepiej traktować jako przenośne formaty zapisu danych, target dla serializowanych danych i źródło danych, które będziemy deserializować i je jakoś obrabiać. Są to formaty tekstowe, więc można je ręcznie oglądać i edytować, jednak wydaje mi się, że to nie jest efektywna metoda pracy z nimi.

YetAnohterone napisał(a):

Po części ten problem występuje także w JSON. Bo jak masz coś takiego:

{
    "blablabla": 1234,
    "pleplepleple": 5678
}

to nie wiesz, czy została tak zserializowana klasa posiadająca dwa pola typu int, czy też słownik mapujący stringi na inty.

JSON się wziął z JS, więc to się deserializuje w JS jednoznacznie - do obiektu o dwóch właściwościach "blablabla" i "pleplepleple", które posiadają określone wartości (1234 i 5678).

Owszem, deserializacja z JSON do innych języków niż JS nie musi być jednoznaczna. W samym JS też ktoś może zapisywać dane w JSON w specjalny sposób (np. dopisać adnotację typów, żeby było wiadomo instancję jakiej klasy utworzyć przy deserializacji), ale to będzie tylko konwencja.

JSON jest elastyczny, ale prymitywny i nie oczekujmy od niego wiele. Dane w JSONie nie muszą mieć sensu semantycznego (o semantykę samemu trzeba zadbać, jeśli się chce mieć coś extra. Są formaty oparte o JSON, ale żeby je sparsować, trzeba mieć wiedzę o tym, w jaki sposób są w tym JSONie zapisane, no niestety).

Trochę jak alfabet łaciński. Zobaczysz coś w obcym języku, który będzie napisany łacinką (bo systemów pisma też jest wiele na świecie), to jakoś to odczytasz, ale niekoniecznie z dobrą wymową ani niekoniecznie zrozumiesz znaczenie.

Nie można zatem zdeserializować JSONa bez wcześniejszej wiedzy, co w tym JSONie może wystąpić i jak się to przekłada na struktury języka programowania.

Mam wrażenie, że chciałbyś zrobić z JSONa jakieś Protocol buffers (które zawierają więcej informacji o typowaniu). Jednak cechą JSONa jest jego prymitywność (co może być równie dobrze wadą jak i zaletą, zależy jak spojrzeć). Bez jakiegoś zewnętrznego umownego schema albo bez znajomości konkretnego formatu opartego o JSON będziesz miał tylko to, co w tym JSON bezpośrednio jest.

0
  1. XML nie jest kupą, ma poważne zalety, choćby przez posiadanie atrybutów, (uznaną schemę itd ale nie o tym wątek). To raczej JSON sztucznie nadrabia brak, np powszechnym (anty)wzorcem podania sztucznej wartości typu obiektu
    { "type" : "sometype" , "value" : "12345.67" }

  2. kupą w każdym strukturalnym formacie serializacyjnym (wyłączam z wypowiedzi CSV i podobne) jest domniemanie, że dwie sekwencyjnie po sobie wartości tworzą spójną parę. Tego nie da sie zagwarantować (można to ratować, ujmując dwie i tylko dwie wartości w nawias, co @YetAnohterone masz w drugim cytacie kodu). Tym niemniej kupa.

  3. JSON nie jest językiem serializacji idealnie pasujacym do wszystkich języków - wywodzi się i pasuje do JS, który nie jest przesadnie wyposażony w typy

1 użytkowników online, w tym zalogowanych: 0, gości: 1