Avatar billede martinm Nybegynder
16. september 2003 - 11:03 Der er 10 kommentarer og
1 løsning

Ópdel string til brug i xsd

Hej,

Jeg har en udfordring mht. en lang streng.

Strengen kan se sådan her ud:

{result(name=id,type=string),(name=age,type=integer)=call storedprocedure([CustomerID IN VARCHAR])

jeg skal parse denne streng igennem og trække name'ets værdi samt typens værdi ud for alle name/type par der eksisterer i strengen(skal bruges til at generere et XSD.

Samtidig skal alt til venstre for call slettes fra strengen.
Avatar billede arne_v Ekspert
16. september 2003 - 11:10 #1
Hvis formatet altid er meget ens kan du jo selv parse linien med noget
indexOf og substring.

Hvis der kan være mange forskellige varianter, så er det måske en ide
at bruge en grammatik og generere en parser med f.eks. JavaCC.
Avatar billede martinm Nybegynder
16. september 2003 - 11:14 #2
Formatet vil altid være på en form med {result(..,..),(..,..)=call osv.

Jeg kan bare ikke komme frem med en løsning. Har forsøgt med StringTokenizer.
Avatar billede arne_v Ekspert
16. september 2003 - 11:34 #3
Her er noget kode til at finde name og type:

public class Parse {

    public static void main(String[] args) {
        process("{result(name=id,type=string),(name=age,type=integer)=call storedprocedure([CustomerID IN VARCHAR])");
    }
    private final static String NAME = "name=";
    private final static String TYPE = "type=";
    public static void process(String s) {
        int ix = 0;
        while (ix < s.length()) {
            int ixname = s.indexOf(NAME, ix);
            if (ixname <= 0)
                ixname = s.length();
            int ixtype = s.indexOf(TYPE, ix);
            if (ixtype <= 0)
                ixtype = s.length();
            if (ixname < ixtype) {
                int ixend = s.indexOf(",", ixname);
                String name = s.substring(ixname + NAME.length(), ixend);
                System.out.println("name: " + name);
                ix = ixend;
            } else if (ixtype < ixname) {
                int ixend = s.indexOf(")", ixtype);
                String name = s.substring(ixtype + TYPE.length(), ixend);
                System.out.println("type: " + name);
                ix = ixend;
            } else {
                ix = s.length();
            }
        }
    }
}
Avatar billede arne_v Ekspert
16. september 2003 - 11:36 #4
Og med call:

public class Parse {

    public static void main(String[] args) {
        process("{result(name=id,type=string),(name=age,type=integer)=call storedprocedure([CustomerID IN VARCHAR])");
    }
    private final static String NAME = "name=";
    private final static String TYPE = "type=";
    private final static String CALL = "call ";
    public static void process(String s) {
        int ix = 0;
        while (ix < s.length()) {
            int ixname = s.indexOf(NAME, ix);
            if (ixname <= 0)
                ixname = s.length();
            int ixtype = s.indexOf(TYPE, ix);
            if (ixtype <= 0)
                ixtype = s.length();
            if (ixname < ixtype) {
                int ixend = s.indexOf(",", ixname);
                String name = s.substring(ixname + NAME.length(), ixend);
                System.out.println("name: " + name);
                ix = ixend;
            } else if (ixtype < ixname) {
                int ixend = s.indexOf(")", ixtype);
                String name = s.substring(ixtype + TYPE.length(), ixend);
                System.out.println("type: " + name);
                ix = ixend;
            } else {
                ix = s.length();
            }
        }
        int ixcall = s.indexOf(CALL);
        String call = s.substring(ixcall);
        System.out.println("call: " + call);
    }
}
Avatar billede arne_v Ekspert
16. september 2003 - 11:38 #5
Den skal muligvis rettes lidt til, men det skulle gerne illustere
brug af indexOf.
Avatar billede arne_v Ekspert
16. september 2003 - 11:39 #6
Altså - den outputter korrekt:

name: id
type: string
name: age
type: integer
call: call storedprocedure([CustomerID IN VARCHAR])

men muligvis skal den kunne håndtere andre konstruktioner.
Avatar billede martinm Nybegynder
16. september 2003 - 11:39 #7
Super! Jeg prøver det lige. Jeg har også set, at StringTokenizer har en constructor med to/tre formelle parametre - mon den også kan bruges. Jeg tester lige det hele.
Avatar billede martinm Nybegynder
16. september 2003 - 11:42 #8
name og type er de eneste to typer, der kan stå i parenteserne. De skal benyttes til at lave xml elementer, der skal være med til at definere at xsd. Det er rent faktisk kolonne navne- og typer fra en database.
Avatar billede arne_v Ekspert
16. september 2003 - 11:59 #9
Det kan godt laves med StringTokenizer, men det er ikke helt nemt, fordi
den kører kun på single character delimiters og derfor skal man
huske state.
Avatar billede arne_v Ekspert
16. september 2003 - 12:06 #10
Altså noget a la:

import java.util.StringTokenizer;

public class Parse2 {

    public static void main(String[] args) {
        process("{result(name=id,type=string),(name=age,type=integer)=call storedprocedure([CustomerID IN VARCHAR])");
    }
    private final static int NONE = 0;
    private final static int NAME = 1;
    private final static int TYPE = 2;
    public static void process(String s) {
        StringTokenizer st = new StringTokenizer(s, "=,()");
        int state = NONE;
        while(st.hasMoreTokens()) {
            String tok = st.nextToken();
            switch(state) {
                case NONE:
                    if(tok.equals("name")) {
                        state = NAME;
                    } else if(tok.equals("type")) {
                        state = TYPE;
                    }
                    break;
                case NAME:
                    System.out.println("name: " + tok);
                    state = NONE;
                    break;
                case TYPE:
                    System.out.println("type: " + tok);
                    state = NONE;
                    break;
            }
        }
    }
}
Avatar billede martinm Nybegynder
16. september 2003 - 13:26 #11
Glimrende Arne! Du er min redningsmand endnu en gang! Det løser min problemstilling!
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
Kurser inden for grundlæggende programmering

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