Sortera data med hjälp av PHP och XML

Permalänk

Sortera data med hjälp av PHP och XML

Hej,

Jag har en XML kod där jag vill skriva ut blad med specifikt sorterad data på. Antalet rader kan variera.

<Row RowNumber="20" RowType="1"><Part PartNumber="077-10468" SupplierPartNumber="35515" /><Text /><ReferenceNumber /><Quantity>15.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>120.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="30" RowType="1"><Part PartNumber="078-0046-1" SupplierPartNumber="35515" /><Text>LOCK Skuren</Text><ReferenceNumber /><Quantity>5.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>145.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="40" RowType="1"><Part PartNumber="095-29745-1" SupplierPartNumber="35550" /><Text>CYLINDERGAVEL Skuren</Text><ReferenceNumber /><Quantity>100.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>528.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="50" RowType="1"><Part PartNumber="096-24204-1" SupplierPartNumber="D4206" /><Text>FÄSTKLAMMA Skuren</Text><ReferenceNumber /><Quantity>50.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>47.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="60" RowType="1"><Part PartNumber="097-55146" SupplierPartNumber="BET3" /><Text /><ReferenceNumber /><Quantity>20.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-20</DeliveryPeriod><Each>16.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="70" RowType="1"><Part PartNumber="098-36032" SupplierPartNumber="BET3" /><Text /><ReferenceNumber /><Quantity>40.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>16.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="80" RowType="1"><Part PartNumber="100-21288-1" SupplierPartNumber="35520" /><Text>ÖRA (KONSOL,HYTTFUNDAMENT) Skuren</Text><ReferenceNumber /><Quantity>20.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>114.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="90" RowType="1"><Part PartNumber="100-21289-1" SupplierPartNumber="35520" /><Text>PLÅT (KONSOL,HYTTFUNDAMENT) Skuren</Text><ReferenceNumber /><Quantity>15.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-29</DeliveryPeriod><Each>598.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row> <Row RowNumber="100" RowType="1"><Part PartNumber="100-22035" SupplierPartNumber="W7010" /><Text /><ReferenceNumber /><Quantity>15.00</Quantity><Unit>st</Unit><DeliveryPeriod>2023-06-20</DeliveryPeriod><Each>32.00</Each><Discount>0.00</Discount><Setup /><Alloy>0.00</Alloy></Row>

Jag hittade hur man läser kod från en .xml fil.

<?php $xml=simplexml_load_file("books.xml") or die("Error: Cannot create object"); foreach($xml->children() as $books) { echo $books->title . ", "; echo $books->author . ", "; echo $books->year . ", "; echo $books->price . "<br>"; } ?>

SupplierPartNumber och DeliveryPeriod måste vara samma, var för sig, för varje "sida" eller hur man nu väljer att presentera datan.

Ex.
Sida 1
Partnumber: 234-14234 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-29
Partnumber: 234-16234 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-29
Partnumber: 233-14254 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-29

Sida 2
Partnumber: 232-14239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-29
Partnumber: 232-14239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-29
Partnumber: 232-14239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-29

Sida 3
Partnumber: 234-94234 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-30
Partnumber: 234-86234 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-30
Partnumber: 233-94254 SupplierPartNumber: 35515 DeliveryPeriod: 2023-06-30

Sida 4
Partnumber: 232-94239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-30
Partnumber: 232-94239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-30
Partnumber: 232-94239 SupplierPartNumber: BET3 DeliveryPeriod: 2023-06-30

Permalänk
Medlem

Jag förstår inte vad din fråga är?

Permalänk
Skrivet av pine-orange:

Jag förstår inte vad din fråga är?

Ursäkta om jag var otydlig, tydligheten försvann väl i ett långt inlägg

Jag skulle behöva hjälp med att ta fram koden för att identifiera taggarna, placera den i en loop och sortera datan.

Permalänk
Medlem

1. Gör om xml raderna till objekt.
2. Använd usort https://www.php.net/manual/en/function.usort.php

Visa signatur

R7-3700X, B450M Mortar MAX, 32GB DDR4 @ 3200, RTX 2080, Corsair CX650M Rev2

Permalänk
Skrivet av Xeno88:

1. Gör om xml raderna till objekt.
2. Använd usort https://www.php.net/manual/en/function.usort.php

Jag är inte så bra på OOP, inte PHP heller egentligen, har mest suttit för att det har varit kul.
Jag hittade lite koder efter lite googlande, vore oerhört tacksam om någon ville sätta ihop koden jag behöver.
Jag gissar att det inte handlar om så många rader/minuter för den som har koll.

Hur man sorterar en array med usort

<?php $array[0] = array('key_a' => 'z', 'key_b' => 'c'); $array[1] = array('key_a' => 'x', 'key_b' => 'b'); $array[2] = array('key_a' => 'y', 'key_b' => 'a'); function build_sorter($key) { return function ($a, $b) use ($key) { return strnatcmp($a[$key], $b[$key]); }; } usort($array, build_sorter('key_b')); foreach ($array as $item) { echo $item['key_a'] . ', ' . $item['key_b'] . "\n"; } ?>

$xml = '<?xml version="1.0"?> <step number="9"> <s_name>test</s_name> <b_sel>12345</b_sel> <b_ind>7</b_ind> </step>'; function convertStepInformationToArray($stepInformation) { $dom = new DOMDocument(); $dom->loadXML($stepInformation); $domx = new DOMXPath($dom); $entries = $domx->evaluate("//step"); return $entries; } print_r(convertStepInformationToArray($xml));

Permalänk

-

Permalänk

Nu har jag lyckats konvertera allt till SQL och sorterar i hämtningen.

Men jag lyckas däremot inte få ut PartNumber och SupplierPartNumber ur denna raden. Antar att det har något att göra med att det ligger innanför taggen. XML-filen måste vara i det formatet som den är, så jag måste lösa det i andra änden. Vore tacksam för hjälp.

PHP

foreach ($xml->children() as $row) { $title = $row->PartNumber; $link = $row->SupplierPartNumber; $description = $row->Quantity; $keywords = $row->DeliveryPeriod;

XML

<Row RowNumber="20" RowType="1"> <Part PartNumber="078-10218" SupplierPartNumber="35515" /> <Text /> <ReferenceNumber /> <Quantity>15.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-29</DeliveryPeriod> <Each>120.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row>

Permalänk
Avstängd

Ofta kan man väl importera XML direkt in i en DB? Jag har gjort det för XML och många andra filformat (Excel, CSV, och så vidare) direkt mot SQL Server med SSMS. Har man den väl i en db kan man ju meka med den hur mycket man vill sen.

Permalänk
Skrivet av snajk:

Ofta kan man väl importera XML direkt in i en DB? Jag har gjort det för XML och många andra filformat (Excel, CSV, och så vidare) direkt mot SQL Server med SSMS. Har man den väl i en db kan man ju meka med den hur mycket man vill sen.

Det är så jag gjort. Laddar in det i SQL och lyckas sortera det rätt. Det funkar när jag kör en XML-fil med bara <rows> och <row> men så fort jag lägger till alla taggar ovanför i koden nedan så slutar den läsa in till databasen. Kan någon tala om vad jag gör för fel i min PHP-kod? Jag antar att det har med children() att göra..?

PHP

foreach ($xml->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod;

XML

<?xml version="1.0" encoding="utf-8"?> <ORDERS420 SoftwareManufacturer="" SoftwareName="MONITOR" SoftwareVersion="23.4.3.22198"> <Order OrderNumber="83"> <Head> <Supplier SupplierCodeEdi="77"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2></StreetBox2> <ZipCity1></ZipCity1> <ZipCity2 /> <Country>Sverige</Country> </Supplier> <Buyer BuyerCodeEdi="13"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country></Country></Buyer><References><BuyerReference></BuyerReference><BuyerComment /><GoodsLabeling><Row1 /><Row2 /></GoodsLabeling></References><DeliveryAddress><Name></Name><StreetBox1></StreetBox1><StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country>Sverige</Country><CompanyAdressFlag>1</CompanyAdressFlag></DeliveryAddress><Terms><DeliveryTerms><IncoTermCombiTerm> </IncoTermCombiTerm><DeliveryMethod>Ändra leveranssätt</DeliveryMethod><TransportPayer>C</TransportPayer><CustomerTransportTimeDays>0</CustomerTransportTimeDays></DeliveryTerms><CustomerInvoiceCode>183</CustomerInvoiceCode><OrderDate>2023-06-14</OrderDate><PaymentTerms><TermsOfPaymentDays>30</TermsOfPaymentDays></PaymentTerms></Terms><Export><Currency>SEK</Currency></Export></Head> <Rows> <Row RowNumber="10" RowType="1"> <Part PartNumber="007-7212-0" SupplierPartNumber="BET3" /> <Text>TEXT, LÅDA</Text> <ReferenceNumber /> <Quantity>20.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-20</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> <Row RowNumber="20" RowType="1"> <Part PartNumber="004-7212-0" SupplierPartNumber="BET3" /> <Text>LÅDA</Text> <ReferenceNumber /> <Quantity>30.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-21</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> </Rows>

Permalänk
Medlem
Skrivet av RobinJacobsson:

Det är så jag gjort. Laddar in det i SQL och lyckas sortera det rätt. Det funkar när jag kör en XML-fil med bara <rows> och <row> men så fort jag lägger till alla taggar ovanför i koden nedan så slutar den läsa in till databasen. Kan någon tala om vad jag gör för fel i min PHP-kod? Jag antar att det har med children() att göra..?

Inte jobbat med PHP sedan länge, men kanske något liknande detta kan leda dig på rätt väg i XML-parsningen:

<?php $xmlString = <<<XML <?xml version="1.0" encoding="utf-8"?> <ORDERS420 SoftwareManufacturer="" SoftwareName="MONITOR" SoftwareVersion="23.4.3.22198"> <Order OrderNumber="83"> <Head> <Supplier SupplierCodeEdi="77"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2></StreetBox2> <ZipCity1></ZipCity1> <ZipCity2 /> <Country>Sverige</Country> </Supplier> <Buyer BuyerCodeEdi="13"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country></Country></Buyer><References><BuyerReference></BuyerReference><BuyerComment /><GoodsLabeling><Row1 /><Row2 /></GoodsLabeling></References><DeliveryAddress><Name></Name><StreetBox1></StreetBox1><StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country>Sverige</Country><CompanyAdressFlag>1</CompanyAdressFlag></DeliveryAddress><Terms><DeliveryTerms><IncoTermCombiTerm> </IncoTermCombiTerm><DeliveryMethod>Ändra leveranssätt</DeliveryMethod><TransportPayer>C</TransportPayer><CustomerTransportTimeDays>0</CustomerTransportTimeDays></DeliveryTerms><CustomerInvoiceCode>183</CustomerInvoiceCode><OrderDate>2023-06-14</OrderDate><PaymentTerms><TermsOfPaymentDays>30</TermsOfPaymentDays></PaymentTerms></Terms><Export><Currency>SEK</Currency></Export></Head> <Rows> <Row RowNumber="10" RowType="1"> <Part PartNumber="007-7212-0" SupplierPartNumber="BET3" /> <Text>TEXT, LÅDA</Text> <ReferenceNumber /> <Quantity>20.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-20</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> <Row RowNumber="20" RowType="1"> <Part PartNumber="004-7212-0" SupplierPartNumber="BET3" /> <Text>LÅDA</Text> <ReferenceNumber /> <Quantity>30.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-21</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> </Rows> </Order> </ORDERS420> XML; $xml = simplexml_load_string($xmlString); foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("$title, $link, $description, $keywords\n"); } }

Permalänk
Skrivet av nimbus:

Inte jobbat med PHP sedan länge, men kanske något liknande detta kan leda dig på rätt väg i XML-parsningen:

<?php $xmlString = <<<XML <?xml version="1.0" encoding="utf-8"?> <ORDERS420 SoftwareManufacturer="" SoftwareName="MONITOR" SoftwareVersion="23.4.3.22198"> <Order OrderNumber="83"> <Head> <Supplier SupplierCodeEdi="77"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2></StreetBox2> <ZipCity1></ZipCity1> <ZipCity2 /> <Country>Sverige</Country> </Supplier> <Buyer BuyerCodeEdi="13"> <Name></Name> <StreetBox1></StreetBox1> <StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country></Country></Buyer><References><BuyerReference></BuyerReference><BuyerComment /><GoodsLabeling><Row1 /><Row2 /></GoodsLabeling></References><DeliveryAddress><Name></Name><StreetBox1></StreetBox1><StreetBox2 /><ZipCity1></ZipCity1><ZipCity2 /><Country>Sverige</Country><CompanyAdressFlag>1</CompanyAdressFlag></DeliveryAddress><Terms><DeliveryTerms><IncoTermCombiTerm> </IncoTermCombiTerm><DeliveryMethod>Ändra leveranssätt</DeliveryMethod><TransportPayer>C</TransportPayer><CustomerTransportTimeDays>0</CustomerTransportTimeDays></DeliveryTerms><CustomerInvoiceCode>183</CustomerInvoiceCode><OrderDate>2023-06-14</OrderDate><PaymentTerms><TermsOfPaymentDays>30</TermsOfPaymentDays></PaymentTerms></Terms><Export><Currency>SEK</Currency></Export></Head> <Rows> <Row RowNumber="10" RowType="1"> <Part PartNumber="007-7212-0" SupplierPartNumber="BET3" /> <Text>TEXT, LÅDA</Text> <ReferenceNumber /> <Quantity>20.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-20</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> <Row RowNumber="20" RowType="1"> <Part PartNumber="004-7212-0" SupplierPartNumber="BET3" /> <Text>LÅDA</Text> <ReferenceNumber /> <Quantity>30.00</Quantity> <Unit>st</Unit> <DeliveryPeriod>2023-06-21</DeliveryPeriod> <Each>24.00</Each> <Discount>0.00</Discount> <Setup /> <Alloy>0.00</Alloy> </Row> </Rows> </Order> </ORDERS420> XML; $xml = simplexml_load_string($xmlString); foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("$title, $link, $description, $keywords\n"); } }

Tack, men jag får det inte att fungera. Detta verkar bygga på en lösning där du modifierat XML-koden, vilket jag inte kan göra.
Vore väldigt tacksam om någon ville hjälpa mig att lösa detta!

Permalänk
Medlem
Skrivet av RobinJacobsson:

Tack, men jag får det inte att fungera. Detta verkar bygga på en lösning där du modifierat XML-koden, vilket jag inte kan göra.
Vore väldigt tacksam om någon ville hjälpa mig att lösa detta!

Jag korrigerade XML-koden eftersom den var invalid för att vara XML, lade bara till slut-taggarna som saknades:

</Order> </ORDERS420>

Om du inte har möjlighet att korrigera XML-koden blir det svårt att parsa ordentligt med den parser du använder.

Förtydligande
Permalänk
Skrivet av nimbus:

Jag korrigerade XML-koden eftersom den var invalid för att vara XML, lade bara till slut-taggarna som saknades:

</Order> </ORDERS420>

Om du inte har möjlighet att korrigera XML-koden blir det svårt att parsa ordentligt med den parser du använder.

Okej,

Såhär är det: Jag har en .xml fil som byts ut varje dag. Den går inte att ändra.
Sedan har jag en index.php där jag kör min PHP-kod, och jag måste kunna läsa från min data.xml därifrån.

Men jag tycker det är konstigt, det fungerar ju som sagt när jag tar bort alla taggar ovanför, det verkar vara något med hur den laddar in taggarna att göra. Gissningsvis children() funktionen eller något i närheten.

Permalänk
Medlem
Skrivet av RobinJacobsson:

Okej,

Såhär är det: Jag har en .xml fil som byts ut varje dag. Den går inte att ändra.
Sedan har jag en index.php där jag kör min PHP-kod, och jag måste kunna läsa från min data.xml därifrån.

Men jag tycker det är konstigt, det fungerar ju som sagt när jag tar bort alla taggar ovanför, det verkar vara något med hur den laddar in taggarna att göra. Gissningsvis children() funktionen eller något i närheten.

Du kommer aldrig att kunna parsa den där XML-filen med en trädbaserad parser som simplexml eftersom den är invalid. När du tar bort taggar ovanför som Order och ORDERS420 så gör du den valid igen. Det första borde vara att försöka få tillgång till en valid XML-fil, dvs åtgärda grundproblemet. Ett alternativ kan vara att läsa in filen, modifiera den innan du sen försöker parsa den genom att lägga till taggar som saknas. Ett annat alternativ kan vara att använda en event-baserad/streamande parser istället, men det är mer krångligt att implementera.

Permalänk
Skrivet av nimbus:

Du kommer aldrig att kunna parsa den där XML-filen med en trädbaserad parser som simplexml eftersom den är invalid. När du tar bort taggar ovanför som Order och ORDERS420 så gör du den valid igen. Det första borde vara att försöka få tillgång till en valid XML-fil, dvs åtgärda grundproblemet. Ett alternativ kan vara att läsa in filen, modifiera den innan du sen försöker parsa den genom att lägga till taggar som saknas. Ett annat alternativ kan vara att använda en event-baserad/streamande parser istället, men det är mer krångligt att implementera.

Ursäkta om jag är otydlig nu. Filen är "valid" om jag förstår dig rätt, dom taggarna finns i slutet, jag har bara tagit bort en massa <Row> taggar för att minska mängden text här i forumet, då har dom antagligen hängt med oavsiktligt.

Men även om jag lägger in dom taggarna så lyckas jag inte få ut den datan jag behöver, med den koden jag har bifogat.
Och ditt exempel kräver ju att jag lägger in PHP-kod i XML-filen, vilket jag tyvärr inte kan göra.

Permalänk
Medlem
Skrivet av RobinJacobsson:

Ursäkta om jag är otydlig nu. Filen är "valid" om jag förstår dig rätt, dom taggarna finns i slutet, jag har bara tagit bort en massa <Row> taggar för att minska mängden text här i forumet, då har dom antagligen hängt med oavsiktligt.

Men även om jag lägger in dom taggarna så lyckas jag inte få ut den datan jag behöver, med den koden jag har bifogat.
Och ditt exempel kräver ju att jag lägger in PHP-kod i XML-filen, vilket jag tyvärr inte kan göra.

Filen är valid om varje start-element har ett motsvarande slut-element (alternativ ett självavslutande element, t.ex. <Foo />). Men att ha ett start-element <Order> och sen ingen matchande </Order> som stänger segmentet är inte rätt.

I mitt exempel använde jag bara en metod för simplexml som tar en sträng istället för fil. Det kvittar vilket man använder. Men återigen så måste innehållet i XML-dokumentet vara korrekt när den parsas på det sättet. Annars vet inte parsern när en Order avslutas och en ny kommer.

Permalänk
Skrivet av nimbus:

Filen är valid om varje start-element har ett motsvarande slut-element (alternativ ett självavslutande element, t.ex. <Foo />). Men att ha ett start-element <Order> och sen ingen matchande </Order> som stänger segmentet är inte rätt.

I mitt exempel använde jag bara en metod för simplexml som tar en sträng istället för fil. Det kvittar vilket man använder. Men återigen så måste innehållet i XML-dokumentet vara korrekt när den parsas på det sättet. Annars vet inte parsern när en Order avslutas och en ny kommer.

Okej, jo men dom finns där. Så utgå från att filen är korrekt. Då undrar jag varför den inte hämtar någon data med denna koden?

$data = "data.xml"; // Load xml file else check connection $xml = simplexml_load_file($data) or die("Error: Cannot create object"); // Assign values foreach ($xml->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod;

Det fungerar som sagt när jag tar bort alla andra taggar och bara kör <Rows><Row>

Permalänk
Medlem
Skrivet av RobinJacobsson:

Okej, jo men dom finns där. Så utgå från att filen är korrekt. Då undrar jag varför den inte hämtar någon data med denna koden?

// Assign values foreach ($xml->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod;

Det fungerar som sagt när jag tar bort alla andra taggar och bara kör <Rows><Row>

Byt ut den där foreach:en mot det jag skickade tidigare, med nästlade foreach (en för varje order, och inuti en för varje rad) så funkar det om filen är korrekt.

Permalänk
Medlem

Felet du gör är att du hämtar alla children i dokumentet, vilket är Order:s. Sen försöker du hämta värden på Order. Men värdena du är ute efter ligger i Row:s i varje Order. Det är därför du behöver iterera två gånger. För att lättare se strukturen på datat kan du indentera XML-dokumentet så framgår det lättare.

Permalänk
Skrivet av nimbus:

Byt ut den där foreach:en mot det jag skickade tidigare, med nästlade foreach (en för varje order, och inuti en för varje rad) så funkar det om filen är korrekt.

Jaha, jag provade den koden förut utan att det funkade. Nu lade jag in den igen och vips så fungerar det.

Dock så uppstår ett nytt problem när jag ska lägga in det i MySQL, den verkar bara ta sista värdet och lägga in. Är det en rimligt lösning att göra ett SQL-anrop varje gång i loopen och fylla databasen på så vis?

Otestad kod, men jag menar ungefär såhär:

foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("$title, $link, $description, $keywords\n<br>"); // SQL query to insert data into xml table $sql = "INSERT INTO xml(PartNumber, SupplierPartNumber, Quantity, DeliveryPeriod) VALUES ('" . $title . "','" . $link . "','" . $description . "','" . $keywords . "')"; $result = mysqli_query($conn, $sql); }

Permalänk
Medlem
Skrivet av RobinJacobsson:

Jaha, jag provade den koden förut utan att det funkade. Nu lade jag in den igen och vips så fungerar det.

Dock så uppstår ett nytt problem när jag ska lägga in det i MySQL, den verkar bara ta sista värdet och lägga in. Är det en rimligt lösning att göra ett SQL-anrop varje gång i loopen och fylla databasen på så vis?

Det funkar nog så länge det inte är enorma datamängder. Men rekommenderar dig att kolla på prepared statements (https://www.php.net/manual/en/mysqli.quickstart.prepared-stat...).

Permalänk
Skrivet av nimbus:

Det funkar nog så länge det inte är enorma datamängder. Men rekommenderar dig att kolla på prepared statements (https://www.php.net/manual/en/mysqli.quickstart.prepared-stat...).

Tusen tack för din hjälp, nu fungerar det som jag vill.

En sista sak jag tänkte på, jag skulle nog föredra en markering (fet stil, eller en border) när datum eller artikel ändras. Eller en dubbel radbrytning.
Jag tänker att man kanske kan sätta en variabel i loopen som jämför föregående data med nästa datarad, och om $ett != $två så infogar man en sådan markering. Är det rätt tänkt? Vore tacksam om någon som har koll vill bidra med kod, annars får jag göra ett försök imorgon

Dvs längst ner i koden där datan presenteras och där någon av nedanstående variablers data varierar. Jag sorterar ju i SQL-query'n efter den datan.
$row['SupplierPartNumber']
$row['DeliveryPeriod']

$data = "data.xml"; $xml = simplexml_load_file($data) or die("Error: Cannot create object"); foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("Artikel: ".$title." Material: ". $link." Antal: ". $description." Datum: ". $keywords."<br>"); $sql = "INSERT INTO xml(PartNumber, SupplierPartNumber, Quantity, DeliveryPeriod) VALUES ('" . $title . "','" . $link . "','" . $description . "','" . $keywords . "')"; $result = mysqli_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } }} ?> <center><h2>Företagsnamnet</h2></center> <center><h1>XML Data storing in MySQL Database</h1></center> <?php if ($affectedRow > 0) { $message = $affectedRow . " records inserted"; } else { $message = "No records inserted"; } $sql2 = "SELECT * FROM xml ORDER BY DeliveryPeriod, SupplierPartNumber"; $result2 = mysqli_query($conn, $sql2); while ($row = mysqli_fetch_assoc($result2)) { echo "Artikel: " . $row['PartNumber'] . "<br> Material: " . $row['SupplierPartNumber'] . "<br> Leveransdatum: " . $row['DeliveryPeriod']."<br> Antal: ".$row['Quantity']."<br><br>"; } ?>

Permalänk

Jag är rätt säker på att så länge du vet att $description alltid är numerisk datatyp så kan du "läs-förenkla" SQL-frågan och skippa concate. Om du vill stoppa in flera gånger vid DB-anropet så använd multi_query där du bygger ihop en lång sträng som innehåller flera SQL-frågor i följd.

<?php // $conn need to have been defined here (or included 'db.php') before running the code below // Declare empty string to add SQL Queries to. $sql = ""; // Now loop through data that will add SQL Queries to $sql foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("Artikel: ".$title." Material: ". $link." Antal: ". $description." Datum: ". $keywords."<br>"); // SQL Injections + XSS Protection mysqli_real_escape_string($conn, strip_tags($title)); mysqli_real_escape_string($conn, strip_tags($tlink)); mysqli_real_escape_string($conn, strip_tags($description)); mysqli_real_escape_string($conn, strip_tags($keywords)); // Add SQL Query to $sql $sql .= "INSERT INTO xml(PartNumber,SupplierPartNumber,Quantity,DeliveryPeriod) VALUES ('$title','$link',$description,'$keywords'); "; }} // Now make multi query with longest $sql string in the world $result = mysqli_multi_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } ?>

Jag hoppas att mitt första läsår som nu snart kommer till sitt slut kan göra någon riktiga nytta online för allra första gången!

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"

Permalänk
Skrivet av WebbkodsLärlingen:

Jag är rätt säker på att så länge du vet att $description alltid är numerisk datatyp så kan du "läs-förenkla" SQL-frågan och skippa concate. Om du vill stoppa in flera gånger vid DB-anropet så använd multi_query där du bygger ihop en lång sträng som innehåller flera SQL-frågor i följd.

<?php // $conn need to have been defined here (or included 'db.php') before running the code below // Declare empty string to add SQL Queries to. $sql = ""; // Now loop through data that will add SQL Queries to $sql foreach ($xml->children() as $order) { foreach ($order->Rows->children() as $row) { $title = $row->Part['PartNumber']; $link = $row->Part['SupplierPartNumber']; $description = $row->Quantity; $keywords = $row->DeliveryPeriod; echo("Artikel: ".$title." Material: ". $link." Antal: ". $description." Datum: ". $keywords."<br>"); // SQL Injections + XSS Protection mysqli_real_escape_string($conn, strip_tags($title)); mysqli_real_escape_string($conn, strip_tags($tlink)); mysqli_real_escape_string($conn, strip_tags($description)); mysqli_real_escape_string($conn, strip_tags($keywords)); // Add SQL Query to $sql $sql .= "INSERT INTO xml(PartNumber,SupplierPartNumber,Quantity,DeliveryPeriod) VALUES ('$title','$link',$description,'$keywords'); "; }} // Now make multi query with longest $sql string in the world $result = mysqli_multi_query($conn, $sql); if (! empty($result)) { $affectedRow ++; } else { $error_message = mysqli_error($conn) . "\n"; } ?>

Jag hoppas att mitt första läsår som nu snart kommer till sitt slut kan göra någon riktiga nytta online för allra första gången!

Mvh,
WKL.

Vi verkar prata olika språk men jag kan utvinna lite svenska mellan raderna
Ska kolla närmre på detta imorgon. Det är dock inga stora mängder data/rader i SQL, vad jag behöver lösa nu är en visuell tydlighet där ett nytt datum - $row['DeliveryPeriod'] eller materialtyp - $row['SupplierPartNumber'] presenteras med en border eller bold text, dvs om det förändras mot förra cykeln i loopen enligt mitt förra inlägg. Vore som sagt väldigt tacksam om någon ville hjälpa mig med en smidig/snygg lösning där.

Permalänk
Skrivet av RobinJacobsson:

Vi verkar prata olika språk men jag kan utvinna lite svenska mellan raderna
Ska kolla närmre på detta imorgon. Det är dock inga stora mängder data/rader i SQL, vad jag behöver lösa nu är en visuell tydlighet där ett nytt datum - $row['DeliveryPeriod'] eller materialtyp - $row['SupplierPartNumber'] presenteras med en border eller bold text, dvs om det förändras mot förra cykeln i loopen enligt mitt förra inlägg. Vore som sagt väldigt tacksam om någon ville hjälpa mig med en smidig/snygg lösning där.

Menar du alltså vid SELECT-frågan där du vill att när ett nytt datum eller nytt materialtyp visas (jämfört med föregående rad) så ska det fetmarkeras så man kan se vilka som verkar höra ihop med samma datum och/eller materialtyp?

$sql2 = "SELECT * FROM xml ORDER BY DeliveryPeriod, SupplierPartNumber"; $result2 = mysqli_query($conn, $sql2); // First declare variables to compare against for every row // First row will have nothing to compare against so it should check it is also empty. $prevPartNumber = ""; $prevDeliveryPeriod = ""; while ($row = mysqli_fetch_assoc($result2)) { echo "Artikel: " . $row['PartNumber']. "<br>"; // Previous row for Part Number is NOT empty and NOT the same? if($prevPartNumber != "" && $row['SupplierPartNumber'] != $prevPartNumber){ echo "<strong>Material: </strong>"; } else { echo "Material: ";} echo $row['SupplierPartNumber'] . "<br>"; // Store current row to act as previous row during next iteration $prevPartNumber = $row['SupplierPartNumber']; echo $row['SupplierPartNumber'] . "<br>"; // Previous row for Delivery Period is NOT empty and NOT the same? if($prevPartDeliveryPeriod != "" && $row['DeliveryPeriod'] != $prevDeliveryPeriod){ echo "<strong>Leveransdatum: </strong>"; } else { echo "Leveransdatum: ";} // Store current row to act as previous row during next iteration $prevDeliveryPeriod = $row['DeliveryPeriod']; echo $row['DeliveryPeriod'] . "<br> Antal: " . $row['Quantity'] . "<br><br>"; }

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"

Permalänk
Skrivet av WebbkodsLärlingen:

Menar du alltså vid SELECT-frågan där du vill att när ett nytt datum eller nytt materialtyp visas (jämfört med föregående rad) så ska det fetmarkeras så man kan se vilka som verkar höra ihop med samma datum och/eller materialtyp?

$sql2 = "SELECT * FROM xml ORDER BY DeliveryPeriod, SupplierPartNumber"; $result2 = mysqli_query($conn, $sql2); // First declare variables to compare against for every row // First row will have nothing to compare against so it should check it is also empty. $prevPartNumber = ""; $prevDeliveryPeriod = ""; while ($row = mysqli_fetch_assoc($result2)) { echo "Artikel: " . $row['PartNumber']. "<br>"; // Previous row for Part Number is NOT empty and NOT the same? if($prevPartNumber != "" && $row['SupplierPartNumber'] != $prevPartNumber){ echo "<strong>Material: </strong>"; } else { echo "Material: ";} echo $row['SupplierPartNumber'] . "<br>"; // Store current row to act as previous row during next iteration $prevPartNumber = $row['SupplierPartNumber']; echo $row['SupplierPartNumber'] . "<br>"; // Previous row for Delivery Period is NOT empty and NOT the same? if($prevPartDeliveryPeriod != "" && $row['DeliveryPeriod'] != $prevDeliveryPeriod){ echo "<strong>Leveransdatum: </strong>"; } else { echo "Leveransdatum: ";} // Store current row to act as previous row during next iteration $prevDeliveryPeriod = $row['DeliveryPeriod']; echo $row['DeliveryPeriod'] . "<br> Antal: " . $row['Quantity'] . "<br><br>"; }

Mvh,
WKL.

Ja, när materialtyp eller datum ändras i listan så vill jag ha en visuell indikation på att en förändring har skett.
Tog några screenshots på hur jag menar.

https://ibb.co/wytxH9B
https://ibb.co/ZctGMKY