• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak wczytać dane z pliku XML do HTML używając JavaScript

VPS Starter Arubacloud
0 głosów
1,676 wizyt
pytanie zadane 8 sierpnia 2018 w JavaScript przez Jumpeq Początkujący (270 p.)

Cześć,
oto mój kod: http://jsfiddle.net/kj1n8uqz/8/
Chciałbym, aby użytkownik po kliknięciu przycisku "Wczytaj" mógł wybrać sobie sam który plik chce wczytać. Dany plik jest wczytywany jako XML i uzupełniany w odpowiednie inputy/selecty i wyświetlony na stronie. Proszę nie piszcie "użyj JSON", do tego zadania mam użyć formatu XML. Jeżeli chodzi o nazwę name, które są takie same jak "choice" i "choice1" to niestety ale muszą takie zostać (przydatne jest to w innych elementach tego zadania którego tutaj nie załączyłem).

Plik XML do wczytania:

 

<?xml version="1.0"?>
<K1>
<punkty name="choice" value="4" checked="false"></punkty>
<punkty name="choice" value="3" checked="false"></punkty>
<punkty name="choice" value="2" checked="false"></punkty>
<punkty name="choice" value="1" checked="false"></punkty>
<punkty name="total" value="0" checked="false"></punkty>
<punkty name="choice1" value="4" checked="false"></punkty>
<punkty name="choice1" value="3" checked="false"></punkty>
<punkty name="choice1" value="2" checked="false"></punkty>
<punkty name="choice1" value="1" checked="false"></punkty>
<punkty name="total1" value="0" checked="false"></punkty>
</K1>
<P1>
<punkty value="5" id="valueOne"></punkty>
<punkty value="0" id="valueOne1"></punkty>
<punkty value="0" id="valueOne2"></punkty>
<punkty value="0" id="valueOne3"></punkty>
<punkty value="3" id="valueOne4"></punkty>
<punkty value="0" id="valueOne5"></punkty>
</P1>

Czy da się to jakoś zrobić? Jeżeli tak to w jaki sposób? Gdzie powinienem szukać rozwiązania? Trochę się z tym męczyłem ale generalnie nie za bardzo wiem od czego zacząć. Wiem, że można spróbować to zrobić AJAX'em na podstawie przykładu który jest tutaj: https://www.w3schools.com/js/js_ajax_xmlfile.asp
Jednak pokazać dane na pustym arkuszu to nie problem, w jaki sposób sprawić aby były wyświetlane w odpowiednich input'ach czy select'ach?
Za wszelkie uwagi/wskazówki byłbym naprawdę bardzo wdzięczny! :)

Pozdrawiam

1 odpowiedź

+2 głosów
odpowiedź 8 sierpnia 2018 przez Comandeer Guru (599,730 p.)
wybrane 11 sierpnia 2018 przez Jumpeq
 
Najlepsza

Po pierwsze, nie polecam W3Schools, a MDN.

Co do samego problemu, najlepiej będzie wczytać ten XML jako dokument i pobrać jego poszczególne elementy, a następnie przenieść ich zawartość do konkretnych elementów na stronie WWW.

komentarz 10 sierpnia 2018 przez Jumpeq Początkujący (270 p.)
Ostatnio nie miałem zbyt czasu i dopiero dzisiaj przysiadłem do zadania bardziej.

Dlaczego nie polecasz W3Schools? Wg mnie są tam bardzo dobre przykłady z wizualizacją. Z MDN korzystam o wiele rzadziej.

Bazując na tym przykładzie: https://www.w3schools.com/xml/tryit.asp?filename=try_dom_loadxmldoc2
Zrobiłem coś takiego: https://next.plnkr.co/edit/rSzSlZuFRpmykZJG
Wartości potrafią załadować się do inputa jeżeli między <punkty>4</punkty> wstawimy jakąś wartość. Jeżeli jej nie ma, nie jestem w stanie wczytać wartości z "value" i sprawienie aby dany checkbox się po wczytaniu zaznaczył. Czy można zrobić to w jakiś prosty sposób?

Zaznaczam, że dopiero zaczynam przygodę z javascript.
1
komentarz 10 sierpnia 2018 przez Comandeer Guru (599,730 p.)

Dlaczego nie polecasz W3Schools?

Podlinkowałem artykuł. Po prostu są tam często popisane bzdury i używane są przestarzałe praktyki.

 Wg mnie są tam bardzo dobre przykłady z wizualizacją.

Na MDN też. Większość przykładów jest także zintegrowana z JSFiddle i CodePenem. 

 

Żeby odczytać zawartość atrybutu, musisz skorzystać z getAttribute, np. xmlDoc.getElementsByTagName( 'punkty' )[ 0 ].getAttribute( 'value' ).

BTW zapisz sobie element do zmiennej, żeby za każdym razem go nie musieć pobierać.

komentarz 10 sierpnia 2018 przez Jumpeq Początkujący (270 p.)
No rozumiem. Zrobiłem coś takiego jak napisałeś:
https://next.plnkr.co/edit/VHsLOHVtSD8eCxEq

Ale checkbox'y nie są zaznaczone. Czy to jest na pewno poprawne? Czy tym przypisuję tylko wartość a checkbox'y muszę zaznaczyć w jakiś inny sposób?

Hmm, zapisać element do jednej zmiennej? Dla każdego input'a wyświetlam inne ID, a także inna wartość jest pobierana.
1
komentarz 10 sierpnia 2018 przez Comandeer Guru (599,730 p.)

Tak, tak dajesz im jedynie value. Żeby zaznaczyć checkbox, musisz ustawić jego własność checked na true.

komentarz 10 sierpnia 2018 przez Jumpeq Początkujący (270 p.)

ale w jaki sposób mam pobrać jego status checked? 
No bo w ten sposób pobieram wartość:
document.getElementById("demo3").value = xmlDoc.getElementsByTagName('punkty')[2].getAttribute( 'value' );
 

A czy tutaj jest pobierany status?
document.getElementById("demo3").value = xmlDoc.getElementsByTagName('punkty')[2].getAttribute( 'checked' );
Jeżeli tak to w jaki sposób sprawić aby został on zaznaczony?
Czy do to tego trzeba napisać jakąś oddzielną funkcję?

1
komentarz 10 sierpnia 2018 przez Comandeer Guru (599,730 p.)

pole.checked = true – tyle wystarczy.

komentarz 11 sierpnia 2018 przez Jumpeq Początkujący (270 p.)

Ok, wielkie dzięki! Generalnie to co reprezentowałem na forum jest wycinkiem większego programu, który zamieszczam tutaj: https://next.plnkr.co/edit/omGJLmlYj48Yz0to
Z góry przepraszam, że jest tego tak dużo i nieczytelnie... przy oddzielaniu kodu js od html wystąpił problem i nic nie działało.

Jak widać, wszystkie dane z pliku XML załadowały i zaznaczyły się poprawnie, jednak pod każdego select'a czy radio button'a są podpięte funkcje które zliczają sumę i na jej podstawie pokazują słownie wskaźnik, czy blokowanie innych select'ów po wyborze innej wartości niż zera, wyznaczenie największe wartości z radio button'ów. Wiem, że może i kod do tych elementów nie wygląda profesjonalnie ale nie o to chodzi. 
To wszystko działa, jeżeli użytkownik na tym operuje ręcznie zaznaczając wartości. Dlaczego po wczytaniu danych z pliku XML te funkcje się nie uruchamiają? Co można zrobić/zastosować aby te wszystkie funkcje zostały odpalone po wczytaniu pliku XML?

Wiem również o tym, że dane wynikowe jak suma/najwyższa wartość też mogę zapisać w pliku XML i też je wczytywać. Ale co w takim razie ze wskaźnikiem który jest przekazywany jako innerHTML? Wiem, że jego nie mogę za bardzo wsadzić do wartości input. A to bardzo ułatwiłoby sprawę z zapisem/odczytem.

Nawet jeżeli udałoby mi się zapisać w jakiś sposób wartość z innerHTML do pliku XML to i tak po wczytaniu pliku XML, funkcja która blokuje inne select'y jeżeli wartość zaznaczona jest różna niż zero musiałaby się uruchomić.

1
komentarz 11 sierpnia 2018 przez Comandeer Guru (599,730 p.)

Tak na pierwszy rzut oka, musiałbyś po prostu uruchomić checkTotal w onreadystatechange.

komentarz 11 sierpnia 2018 przez Jumpeq Początkujący (270 p.)

Problem obszedłem w inny sposób. Zamiast tego zamieniłem select'y na radio buttony, wyniki jak suma czy wskaźniki zamiłem na value i tak też zapisuję i wczytuję dane bez żadnego problemu. 
https://next.plnkr.co/edit/HEH78KZFV1GDo9Mv
Ten kod nie jest uaktualniony w to co zmieniłem, chodzi mi o coś innego. O możliwość wczytania tego pliku przez użytkownika, a nie w kodzie podając jego nazwę. Aby było czytelniej:
Kod, który ładuje się na stronie:
 

<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "data.xml", true);
xhttp.send();

function myFunction(xml) {
    var xmlDoc = xml.responseXML;   
	
	document.getElementById("input1K1S1").value = xmlDoc.getElementsByTagName('punktyk1')[0].getAttribute( 'value' );
	document.getElementById("input1K1S1").checked = (xmlDoc.getElementsByTagName('punktyk1')[0].getAttribute( 'checked' )== 'true');
	
	document.getElementById("valueOne").value = xmlDoc.getElementsByTagName('punktyp1')[0].getAttribute( 'value' );
	
}
</script>

A tutaj kod wybrania pliku z dysku:
 

<script>
function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
  };
  reader.readAsText(file);
}

function displayContents(contents) {
  var element = document.getElementById('file-content');
  element.textContent = contents;
}

document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);
</script>
<input type="file" id="file-input" />

W miejsce "data.xml" chciałem wstawić "readSingleFile" ale to nie pomogło. W jaki sposób to połączyć? W jaki sposób sprawić aby plik, który wybierzemy z pulpitu załadował się tak samo jak "data.xml"?

1
komentarz 11 sierpnia 2018 przez Comandeer Guru (599,730 p.)

Hmm, jedyne, co mi przychodzi do głowy, to wyciągniętą z pliku treść przemielić przez DOMParser.

komentarz 11 sierpnia 2018 przez Jumpeq Początkujący (270 p.)
Nie ma na to prostszego sposobu? No bo jeżeli xhttp łapie plik który jest w tym samym folderze, tak też wydaje mi się, że mógłby złapać plik, który jest gdziekolwiek na dysku. Tylko nie wiem w jaki sposób to przekazać :(
1
komentarz 11 sierpnia 2018 przez Comandeer Guru (599,730 p.)

Nie da się. Dysk użytkownika to dla strony internetowej obszar całkowicie nieistniejący. Zresztą nic dziwnego, bo problemy z bezpieczeństwem, które z tego wynikają, mogą być naprawdę spore.

No i najważniejsza różnica: pliki wczytywane przez xhr są na serwerze, nie na dysku użytkownika.

komentarz 11 sierpnia 2018 przez Jumpeq Początkujący (270 p.)
Rozumiem, a czy można w xhttp.open w miejsce "data.xml" wstawić nazwę pliku, która jest pobrana za pomocą php? Jeżeli tak to czym powinienem się zainteresować, aby ten plik wgrać na serwer aby xhttp go odczytał?
1
komentarz 11 sierpnia 2018 przez Comandeer Guru (599,730 p.)

No można, tylko czemu nie chcesz wykorzystać pliku, który wczytujesz przy pomocy FileReader? Wydaje się to prostsze niż takie kombinowanie.

komentarz 11 sierpnia 2018 przez Jumpeq Początkujący (270 p.)
Nie za bardzo ogarniam tego DOM parser'a dlatego pytam o php
komentarz 14 sierpnia 2018 przez Jumpeq Początkujący (270 p.)

Kod działa, robi wszystko to co chcę, tutaj link: https://next.plnkr.co/edit/9kRLWf2OiaRcJaqj (niestety nie działa poprawnie, trzeba odpalić w xamppie dla testowania)

Jest jedno ale. Jeżeli będzie dwóch użytkowników, użytkownik X i Y. Załóżmy, że użytkownik X wypełnił formularz, zapisał go i wgrał na serwer i skończył. Wtedy plik dalej jest na serwerze, jeżeli użytkownik Y chce wypełnić formularz ma wypełniony przez użytkownika X. W jaki sposób zrobić coś takiego, że jeżeli pierwszy raz wchodzimy na stronę (nie wiem odświeżenie czy coś) to wszystkie pliki z katalogu "uploads" są usuwane?
Druga opcja na rozwiązanie tego problemu to zapisywanie pliku .xml pod unikalną nazwą w folderze "uploads" i dany parametr przekazywanie do:

xhttp.open("GET", "uploads/xml", true);


Pytanie w jaki sposób w miejsce "uploads/xml" przekazać nazwę pliku zapisanego parametru, który jest generowany w PHP?

1
komentarz 14 sierpnia 2018 przez Comandeer Guru (599,730 p.)

A jeśli kod JS byłby generowany przez PHP? Wówczas po prostu podstawiałoby się zawartość zmiennej.

Albo generować przez PHP zmienną globalną z nazwą pliku i ją tam użyć:

window.sessionId = '<?=$generatedCode;?>';

 

komentarz 18 sierpnia 2018 przez Jumpeq Początkujący (270 p.)

Generalnie problem już prawie rozwiązałem ale dręczy mnie jedna sprawa (tutaj dostępny kod: https://next.plnkr.co/edit/9kRLWf2OiaRcJaqj?preview )
Chciałbym aby po wgraniu danych na serwer i zczytaniu informacji plik od razu został usunięty. Jak narazie jestem to w stanie po kliknięciu button'a z przekierowaniem "delete.php"
 

<?php    
    $source = 'data.xml';
    unlink($source);
?>

Jednak w jaki sposób to zrobić aby po kliknięciu na przycisk "Upload" uruchomić w PHP usuwanie tego pliku, aby informacje zdążyły się zczytać a następnie plik został usunięty?

komentarz 18 sierpnia 2018 przez Comandeer Guru (599,730 p.)
A czemu nie zrobisz drugiego żądania Ajaksowego po tym jak zakończysz obrabiać pierwsze?

Podobne pytania

0 głosów
0 odpowiedzi 271 wizyt
pytanie zadane 8 czerwca 2017 w JavaScript przez Damian Prymus Początkujący (380 p.)
+1 głos
2 odpowiedzi 151 wizyt
pytanie zadane 21 września 2020 w JavaScript przez komar54 Użytkownik (830 p.)
0 głosów
1 odpowiedź 1,046 wizyt
pytanie zadane 27 października 2016 w JavaScript przez Newperty Początkujący (280 p.)

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...