- 2Lazy
- Medlem ●
- Stockholm
Hej igen,
Håller på att skriva ett skript för att importera av stort antal xml-filer.
Eftersom poster, med innehåll som är skrivna av andra, kan innehålla "vadsomhelst" har jag nu träffat på en massa överraskningar och bifogar ett av exemplen, se bilagda .zip-fil.
I xml-dokumentet i bilagan på rad 53 finns detta problem :
<player><rank>23</rank><login>blomqvist</login><nickname>Blom $F00<KKND Team></nickname><time>DNF</time></player>
Problemet ligger i att en del av namnet i <nickname>-taggen innehåller detta: <KKND Team>
FileMaker genererar ett error och kan INTE importera xml-filen via xml-importen!
Kan man komma runt detta i XSLT-filen, eller på något annat sätt, så att det inte
kräver manuellt arbete eller editering i själva xml-filen?
(det rör sig om 100 000 tals filer sammanlagt)
Finns det några fler tecken som kan orsaka error vid xml-import till FM?
Det beror lite på hur den ursprungliga XML-filen ser ut, men i grunden är det bara ett fåtal tecken som är reserverade och som måste särbehandlas, se t.ex:
För att vara helt säker på vad det beror på måste man analysera källfilen lite närmare.
Den XML-filen är inte giltig. Den innehåller något av de tecken som Richard hänvisade till. Problemet är texten "<KKND Team>" som inte kan tolkas som XML-tag (innehåller mellanslag och saknar avslutande tag). Det borde kodas som "<KKND Team>" för att det bli en giltig XML-fil.
En ogiltig XML-fil kan inte öppnas eller importeras.
Problemet är; Eftersom innehållet är skrivna av andra, kan det innehålla "vadsomhelst" och fenomenet förekommer därför ENDAST inom taggen <nickname>.
Det optimala vore om man kunde åstadkomma någon filtrering i XSLT, annars måste man först filtrera alla xml - innan inläsning kan ske & då måste alla cvs filer filtreras på samma sätt - så innehållet är identisk jämförbart (security checkar bygger på detta).
Personligen tycker jag det snarare är ett programfel i FM! Taggen innehåller ett mellanslag, ligger "innerst" och borde "som default" betraktas som text fram till dess det finns en motsvarande avslutstagg.
Tänk om xml skulle användas inom ekonomiska rapporter!
- ska FM inte klara inläsning av något som först är "mindre än" och sen "större än"... ;=o)
Samtidigt är det ju klantigt av företaget som skrivit programmet - att tillåta tagg-förekomster i nickname-taggen som nu är fallet.
I tidigare csv filer var motsvarande problem " (citat)-tkn - som vid förekomst slog ut importen. Det var dock enkelt att filtrera bort INNAN inläsning.
Går det att skriva en Grep-sökning och ersätta alla < till <? och samtidigt ta bort alla " (tkn) inom nickname-taggen
Är det någon som vet?
Problemet ligger inte hos FileMaker... Problemet ligger hos de som skapar XML-filerna, filerna måste vara giltiga. Det finns inte några program som klarar av att öppna ogiltiga XML-filer (som XML).
Det du kan göra är att byta ut otillåtna tecken i XML-filerna innan importen t.ex. med något program som ändrar i alla XML-filer (som ju är textfiler) samtidigt med GREP eller annan teknologi, om nu inte de som skapar XML-filerna kan göra giltiga sådana.
Teckenkoden "<" i XML-filen tolkas och importeras som "<" i FileMaker.
Och XML används för ekonomiska rapporter...
Är det någon som kan "Grep" tillräckligt för att byta ut alla < > " ' & - tkn? inom taggen <nickname> ?
- ( och då ta bort alla " tkn)
Går det att skriva en JAVA-snutt som utför detta?
ALTERNATIVET är att först IMPORTERA in HELA text-innehållet i filen till en nyskriven FM snutt och därifrån sen skriva en funktion som filtrerar om allt mellan <nickname>-taggarna och sen skriva tillbaka filen med angivna standardtecken!
Går det ? Hur i så fall?
Är det någon som kan "Grep" tillräckligt för att byta ut alla < > " ' & - tkn? inom taggen <nickname> ?
Det finns det, jag bland annat, men för egen del känner jag att det i så fall får ske inom ramen för ett betalt uppdrag. Är du intresserad av det finns kontaktinformation under min profil.
Är det någon som kan "Grep" tillräckligt för att byta ut alla < > " ' & - tkn? inom taggen <nickname> ?
Grep (Generalized Regular Expression Parser) används bara för att hitta information.
Använd Perl istället. Några exempel i länken.
Dev Shed Forums - View Single Post - Unix find and replace text within all files within a directory
Grep finns som en del av sökfunktionen i bbedit vilket gör att Grep även kan ersätta "det den hittar".
Vad jag inte "kan"/vet är om grep kan leta upp ett enskilt speciellt tecken mellan TVÅ FASTA definitioner (positioner) = <nickname></nickname>, alltså söka upp de 5 förbjudna tecknen mellan start och stop tagg och sen byta ut dem till alt-tecken, eller ascii numerisk kod.
Problemet ligger inte hos FileMaker... Problemet ligger hos de som skapar XML-filerna, filerna måste vara giltiga. Det finns inte några program som klarar av att öppna ogiltiga XML-filer (som XML).
.
JO -> felet ligger i FM:s sätt att ta in informationen - om "själva" erroret uppkommer i FM eller inte -är svårt att säga -> här är beviset på att det går "på annat sätt" - men processen tar 2-3 sek längre per fil x 100 000 så blir det rätt många timmar:
Ladda först hem Troi-File-Plug-in5.0.1 samt TrText Plug-in 3.0.1 och kör sedan följande beräkning med import till 2 textfält (TEST samt Tillfällig_XML_variabel). Processen måste uppdelas i två steg med en förekomstberäkning av <player> ( som i exemplet motsvarar 27):
1. Värde för "TEST"-fältet =
TrFile_GetContents( "-ConvertToFMPLinebreaks" ; Sökväg till mappen & filnamn )
- därefter beräknas förekomsten av <player> i textfältet "TEST" som blir = $loop
2. Värde för "Tillfällig_XML_variabel" fältet i en loop! $loop = förekomster av <player> taggen
TrText_XML( "-GetNode" ; "race/results/player[" & GetAsNumber ($loop) & "] /rank ";TEST ) & "," & TrText_XML( "-GetNode" ; "race/results/player[" & GetAsNumber ($loop) & "] /time"; TEST ) & "," & TrText_XML( "-GetNode" ; "race/results/player[" & GetAsNumber ($loop) & "] /login" ; TEST ) & "," & TrText_XML( "-GetNode" ; "race/results/player[" & GetAsNumber ($loop) & "] /nickname" ; TEST ) & "¶"
Detta är en lösning på problemet - (som jag kom på alldeles själv) - som fungerar - men den är inte optimal.
Frågan för mig är nu ett c++ program som rättar felen inne i dokument-taggarna i stället.
Informationen blir ju då mer flexibel och korrekt, samt snabbare att hantera & utbyta.
OM xml-filen innehåller den taggen, uttryckt på det sätt som du visar i exemplet så är det inte giltig (well-formed) XML, dvs det är inte XML alls!
Precis som Rolf säger gör FileMaker rätt. Det finns ohyggligt goda skäl för att inte tillåta < och > i text (vilket dock kan uppnås med CDATA-sektioner alternativt teckenkoder)
Rätt ställe att fixa ett sånt problem är egentligen före/i samband med exporten till XML. Går inte det får man lösa det med hjälp av andra verktyg för att tvätta text.
Är inte det lättaste att köra en sök och ersätt från "<nickname>" till "<nickname><=!=[=C=D=A=T=A=[” och "</nickname>" till "]=]=></nickname>" ?
Jo, den här lösningen fungerar jättebra! - Missuppfattade detta till en början.
Undrar nu om [CDATA[ ]] - uttrycket innebär att alla pars-kontroller "stängs av" ?
Är det i så fall inte möjligt att lägga CDATA-instruktionen i XSLT - dokumentet - avseende för <nickname>-taggen?
Är det i så fall inte möjligt att lägga CDATA-instruktionen i XSLT - dokumentet - avseende för <nickname>-taggen?
Om jag fattar rätt så används XSLT-dokumentet för att knöla om din XML-fil (med de felaktiga innehållet i <nickname>) till ett XML-dokument som FileMaker kan läsa in i sina tabeller?
I så fall är nog svaret nej. XSLT är till för att transformera ett giltigt XML-dokument till något annat, och eftersom ditt källdokument inte är giltig XML borde ingen XSLT-transformation i världen råda bot på det.
Du får nog köra Hagelins trix på filerna innan du gör något annat med dem...
La ihop alla andras kunskaper och jag tror jag tänkt fram en lösning som fungerar.
Provkörde just nu den här del-taggen, i stället för "select" i <DATA> taggen i XSLT - hjälpfilen, och vips så funkade det...
<xsl:value-of cdata-section-elements="nickname" />
Summa = 3 olika alternativa lösningar på problemet, nu känns det som jag är hemma....
Min nya FM-lösning med Troi, se tidigare inlägg - la jag som backup OM error "trots allt" uppstår, så den körs bara om ordinarie importen orsakar error. Så förlusten i inläsningstid var marginell - men efter omskrivningen i XSLT-filen, lär den nog aldrig behövas.
Tack alla kloka - varje råd ni gav gick att kombinera...
Vad som är lättast vet jag inte, men eftersom bbedit har en inbyggd multifile search, så kan den ersätta allt på en gång.
Har t ex använd BBDEDIT:s Multifilesearch för att söka och ta bort alla " - som orsakade inläsningsfel för FM i gamla csv-filerna och det tog bara 1,5 sek att köra igenom 2500 filer, med ca 6 000 ersättningar.
Problemet är att jag inte kan "Grep" helt och hållet, men här är ett simpelt exempel som skulle markerar tagg + utrymmet mellan , inkl avslutstagg: <nickname>.*?</nickname>
FileMaker gör rätt. En del av XML-standarden är nämligen att felaktig XML aldrig får "tolkas" och "korrigeras". Anledningen till det är att W3C när de skapade XML inte på nytt ville hamna i HTML-träsket, där varje parser funkar annorlunda pga. att de försöker "fixa" problem.
Nu finns det förvisso många sätt att åstadkomma ett fungerande resultat, men om felet bara består av det du har nämnt behövs ingen GREP-sökning alls. Den lösning som Hagelin nämner är briljant i sin enkelhet och borde fungera utmärkt, om förutsättningarna är de du uppgett.
FileMaker gör rätt. En del av XML-standarden är nämligen att felaktig XML aldrig får "tolkas" och "korrigeras". Anledningen till det är att W3C när de skapade XML inte på nytt ville hamna i HTML-träsket, där varje parser funkar annorlunda pga. att de försöker "fixa" problem.
I mitt projekt samarbetar jag med en Amerikan, han kom med ett svar på lösning! CITAT:
I ran into this problem when I built my system to parse nicknames from the API.
I solved it quickly by passing the file through a simple filter.
a built in PHP function that solved my problem:
$clean = mb_convert_encoding($xml, "UTF-8");
Detta betyder ju att man kan konvertera det felaktiga taggarna i PHP - varför går det då inte att skapa en filtreringskommando i xml?
Pust - nu måste man blanda in ytterligare ett programspråk...
CDATA-lösningen fungerade ända tills jag träffade på detta nickname: ]]</_} FISH ≤°((|))><
Kul med kreativitet - eller hur...!
Detta betyder ju att man kan konvertera det felaktiga taggarna i PHP - varför går det då inte att skapa en filtreringskommando i xml?
Därför att ett filtrerinskommando i XML (eller snarare XSLT) bygger på att det du skickar in till fitreringen är korrekt XML. Är det inte korrekt XML ska en väluppfostrad XML-tolkare ge upp och låta något annat ta hand om det istället.
Men det finns inget som hindrar att du tar vilket annat verktyg som helst (Grep, PHP, 1000 apor, ...) och göra vad du vill med en sån fil. Som t.ex. försöka reparera den så att den blir korrekt XML.
Vill du gå till botten av ditt problem måste du nog gå på dem som tillverkar de s.k. XML-filerna och se till att de verkligen levererar korrekt XML.
Du får väl skriva en kodsnutt "tvättar" XML-filerna genom att leta upp all text som står mellan <nickname> och </nickname>, och ersätter alla &, <, >, ' och " i den med motsvarande XML-kodning. Kör den innan du importerar XML-filen i FileMaker.
Det kan fungera ända till nån kommer på iden att ha ett nickname som innehåller "</nickname>"...
Du får väl skriva en kodsnutt "tvättar" XML-filerna genom att leta upp all text som står mellan <nickname> och </nickname>, och ersätter alla &, <, >, ' och " i den med motsvarande XML-kodning. Kör den innan du importerar XML-filen i FileMaker.
Det kan fungera ända till nån kommer på iden att ha ett nickname som innehåller "</nickname>"...
Med grep kan det fungera ändå, eftersom man kan ha "greedy" respektive "lazy" matchning
Med grep kan det fungera ändå, eftersom man kan ha "greedy" respektive "lazy" matchning
Det går säkert att lösa väldigt mycket, det gäller bara att tänka på vilka problem som kan uppstå med den lösning man väljer. Och med tanke på hur kreativa användare som verkar finnas tar det inte lång tid innan nån tar ett nickname som innehåller "</nickname><nickname>"...
Men oavsett hade jag gått på samma lösning som du.
Det går säkert att lösa väldigt mycket, det gäller bara att tänka på vilka problem som kan uppstå med den lösning man väljer. Och med tanke på hur kreativa användare som verkar finnas tar det inte lång tid innan nån tar ett nickname som innehåller "</nickname><nickname>"...
Men oavsett hade jag gått på samma lösning som du.
Kan inte låta bli att avvika från trådämnet en smula. Snabb brief är: Jag diskuterar på en annan site med programutvecklare om deras problem med xml. Deras moderator skriver så här:
I suspect that Nadeo does not use the almost-XML files or they would have noticed the problem themselves. The only purpose for the XML results file is for the player's use, and it is not very useful, and potentially dangerous, if the files are mal-formed.
I think I'll change my nickname to CanKnot</nickname><time>1</time></player></file><!-- and see if I can boost my online standings Clin d'oeil
_________________
In theory there is no difference between theory and practice, but in practice there is.
Det finns ca 50 000 kreativa spel-användare idag och det räcker med några "medvetna" obstruktioner på namnet så är det kört...
Den här tråden illustrerar väl varför vi konsulter behövs
Personligen skulle jag tvätta texten med grep, och sedan transformera alla i ett svep, och fånga eventuellt felaktiga filer, innan de importeras till FileMaker.