Avatar billede heyn Nybegynder
18. marts 2010 - 10:37 Der er 13 kommentarer og
1 løsning

En nybegynder skal ændre få data i en meget stor xml-fil

Hej Eksperter.

Jeg er HELT nybegynder i XML. Jeg kan dog forstå logikken og strukturen.
Jeg står og skal udvikle et php-script der ændre nogle nogle få punkter i et meget stort xml-dokument (>300.000 linier) hvis visse conditions er opfyldt for taget <produkt> i dokumentet.
Der er mere end 3000 objekter af <produkt>...</produkt> i dokumentet.

Har nogen en ide til hvordan det bedst gøres i php?

Mvh og godt forår fra Christian
Avatar billede heyn Nybegynder
18. marts 2010 - 10:38 #1
De data jeg skal ændre i xml-dokumentet henter jeg fra en mysql-db.
Avatar billede repox Seniormester
18. marts 2010 - 10:43 #2
Avatar billede heyn Nybegynder
18. marts 2010 - 11:06 #3
Som nævnt - Jeg er nybegynder.

xml-dokumentets struktur er bl.a.

<PRODUCT_EXPORT type="PRODUCTS">
  <ELEMENTS>
...
...
    <PRODUCT>
      <GENERAL>
        <PROD_NUM>010-00783-43</PROD_NUM>
        <LANGUAGE_ID>26</LANGUAGE_ID>
        <EDBPriser_NUM>010-00783-43</EDBPriser_NUM>
      </GENERAL>
      <STOCK>
        <STOCK_COUNT>0</STOCK_COUNT>
      </STOCK>
      <PRICES>
        <PRICE>
          <CURRENCY_CODE>DKK</CURRENCY_CODE>
          <UNIT_PRICE>655,20</UNIT_PRICE>
        </PRICE>
      </PRICES>
    </PRODUCT>
...
...
  </ELEMENTS>
</PRODUCT_EXPORT>

Hvis data for <STOCK_COUNT> er mindre end 1 og forskellige fra de tilsvarende data i mysql-db skal <STOCK_COUNT> og evt. også <UNIT_PRICE> ændres.

mvh Christian
Avatar billede repox Seniormester
18. marts 2010 - 11:36 #4
Det er jo et større script du skal have lavet. Først skal du løbe alle dataene igennem, for derefter at gendanne dem på ny.

At løbe produkterne igennem, en for en, er relativt simpel:
  $xml = new SimpleXMLElement($xmlString);
  foreach($xml->ELEMENTS->PRODUCT as $product)
  {
    //hent indholdet af STOCK_COUNT
    $stock_count = (int)$product->STOCK->STOCK_COUNT;
  }


Der er dit sammenligningsgrundlag.
For at danne XML med SimpleXML, skal du kigge på addChild funktionen som du kan finde her: http://www.php.net/manual/en/simplexmlelement.addChild.php

Der er et fint eksempel på hvordan du kan tilføje elementer og childs i din xml.
Avatar billede heyn Nybegynder
18. marts 2010 - 11:45 #5
Vil det sige at jeg skal

1) Indlæse alle data i et array.
2) Checke op med data i mysql, og evt. synkronisere data.
3) Oprette et nyt xml-dokument med alle værdierne fra arrayet, såvel gamle som nye.

Er det ikke muligt at ændre en enkelt data el. 2 i dokumentet uden at genoprette det helt fra nyt?
Avatar billede repox Seniormester
18. marts 2010 - 12:34 #6
Det var en måde at gøre det på, ja...
Men jeg ville nok gøre noget lidt mere synkront; evt. konkattenere en XML streng ud fra det aktuelle produkt. Så slipper jeg den store opdeling.
Avatar billede heyn Nybegynder
19. marts 2010 - 08:19 #7
Lad mig give et simpelt eksempel på hvad jeg mener.
Jeg har følgende xml-dokument xmltest.xml

<?xml version="1.0" encoding="iso-8859-1"?>
<LEVEL_1>
  <LEVEL_2>
    <ID>5795</ID>
    <PERSON>Hans</PERSON>
    <VALUE>Har du det godt</VALUE>
  </LEVEL_2>
  <LEVEL_2>
    <ID>AF-789</ID>
    <PERSON>Viggo</PERSON>
    <VALUE>Ja jeg har</VALUE>
  </LEVEL_2>
  <LEVEL_2>
    <ID>123ADF</ID>
    <PERSON>Hans</PERSON>
    <VALUE>Godt at høre</VALUE>
  </LEVEL_2>
</LEVEL_1>

Nu ønsker jeg at ændre Viggos indlæg således at det istedet bliver:

<VALUE>Nogle gange<VALUE>

Jeg vil finde frem til det rigtige objekt af <LEVEL_2> ved at søge på <ID>AF-789</ID>.
Jeg er noget så langt at jeg mener at skulle starte med:

<?php
$xml = $xml = simplexml_load_file('/.xmltest.xml');

Men hvad jeg derefter skal gøre kan jeg ikke greje.

Jeg er heller ikke klar over hvordan jeg på tilsvarende vis tilføjer og sletter objekter af <LEVEL_2> og endelig gemmer de nye forandringer.
Hvis jeg kender trick'ne til dette lille eksempel vil jeg være meget langt, og klar til at gå i gang selv.

Håber en kan hjælpe mig.

God weekend.

Jeg tror at jeg vil være nået meget langt og være klar til at
Avatar billede repox Seniormester
19. marts 2010 - 10:21 #8
Med udgangspunkt i dit sidste XML eksempel:
    header("Content-Type: text/xml; charset=ISO-8859-1");
    $xml = new SimpleXMLElement( file_get_contents("./xmltest.xml") );
   
    foreach($xml->LEVEL_2 as $level2)
    {
        if((string)$level2->ID == "AF-789")
            $level2->VALUE = "Nogle gange";
    }
   
    echo $xml->asXML();
Avatar billede heyn Nybegynder
19. marts 2010 - 10:31 #9
Så lykkedes det meste, da jeg først fandt ud af at funktionerne er casecensitive. Jeg har gjort følgende:

<?php
$xmlfile ="./xmltest.xml";
if (!$xml = simplexml_load_file($xmlfile));

foreach ($xml->PERSON as $person){
    echo $person->NAME." siger: ".$person->VALUE."<br>";
    if ($person->ID == "AF-789") $person->VALUE = "Nogle gange.";
}

echo "<br>";
foreach ($xml->PERSON as $person){ echo $person->NAME." siger: ".$person->VALUE."<br>"; }
?>

Men jeg kan ikke finde ud af hvordan jeg skal tilføje mine forandringer xmltest.xml og uploade det.
Lad os sige jeg skal uploade det til http://localhost/.
Hvilken simplexml funktion skal jeg bruge?
Er det muligt kun at uploade forandringerne når det sker på localhost. Som nævnt er min xml-fil meget stor?
Avatar billede repox Seniormester
19. marts 2010 - 10:41 #10
Jeg bliver lidt forvirret af at du kalder det 'uploade'? Du har jo allerede dataene lokalt?

Never the less, dit oprindelige spørgsmål gik på at du gerne ville ændre indholdet af din XML. Nu går du så over og begynder at behandle indhold, udskrive det og så ikke anvende indholdet til noget. Du bør lave en bedre opdeling; behandl dine data, smid dem i din XML fil, udskriv dine data fra din XML fil.

Du kan ikke bruge SimpleXML fil til at 'uploade' noget som helst; SimpleXML indhenter og behandler XML; ikke andet...

Hvis du vil skrive din XML til en fil skal du gøre noget ala:
file_put_contents( $xmlfile, $xml->asXML() );
Avatar billede heyn Nybegynder
19. marts 2010 - 10:55 #11
Lad mig prøve at forklare.
Det viste eksempel er udelukkende for at vise at jeg har foretaget en forandring midt i mit xml-objekt, som altså er et eksempel.
Når Jeg når til den egentlige opgave vil jeg gå anderledes til værks.
Det jeg kan nu er:
1) Hente en xmlfil og lave den om til et xml-objekt.
2) Ændre i objektet når visse conditions er opfyldt.

Og nu skal jeg - nybegynderen altså bare vide hvordan jeg:

3) Laver mit forandrede xml-objekt om til en xml-fil og og overskriver den oprindelige xml-fil xmltest.xml med den nye.

Jeg vil være dig meget taknemmelig hvis du har en ide.
Avatar billede repox Seniormester
19. marts 2010 - 11:05 #12
Det har du fået?
Jeg kan da godt ændre den sidste linie for dig, hvis det gør det nemmere...
    $xmlfile = "./testxml.xml";
    $xml = new SimpleXMLElement( file_get_contents("./xmltest.xml") );
   
    foreach($xml->LEVEL_2 as $level2)
    {
        if((string)$level2->ID == "AF-789")
            $level2->VALUE = "Nogle gange";
    }

    file_put_contents( $xmlfile, $xml->asXML() );
Avatar billede heyn Nybegynder
19. marts 2010 - 11:09 #13
Ah - I get it! Det med file_put_contents.

Og mange tak for den store hjælp.

Smider du et svar.
Avatar billede repox Seniormester
19. marts 2010 - 11:12 #14
Det fik du her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester