Avatar billede HeleneHH Nybegynder
19. juni 2013 - 07:53 Der er 14 kommentarer og
1 løsning

xpath og uml

Hej

Hvordan kan jeg få fat i UML:Class vha xpath

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <XMI xmi.version="1.1" xmlns:UML="//org.omg/UML/1.3" timestamp="17. juni 2013 14:24:09">
        <XMI.header>
            <XMI.documentation>
                <XMI.exporter>
                </XMI.exporter>
                <XMI.exporterVersion>
                </XMI.exporterVersion>
            </XMI.documentation>
            <XMI.metamodel xmi.name="UML" xmi.version="1.4">
            </XMI.metamodel>
        </XMI.header>
        <XMI.content>
            <UML:Model xmi.id="ML1" name="HHClassTest" visibility="public">
                <UML:Namespace.ownedElement>
                    <UML:Class xmi.id="_0.0-105.743..148_" name="ClassA" visibility="public" isAbstract="false" namespace="">
                        <UML:Classifier.feature>
Avatar billede arne_v Ekspert
20. juni 2013 - 01:21 #1
//XMI/XMI.Content/UML:Model/UML:Namespace.ownedElement/UML:Class

men XPath skal informeres om namespacet UML.

Hvilket sprog/framework bruger du.
Avatar billede HeleneHH Nybegynder
20. juni 2013 - 21:02 #2
super tak. hvordan får point?
Avatar billede arne_v Ekspert
20. juni 2013 - 23:53 #3
jeg smider et svar
Avatar billede HeleneHH Nybegynder
24. juni 2013 - 13:54 #4
Arne, jeg var måske lidt hurtig. Jeg ved ikke om jeg skal lave et nyt spørgsmål... men hvordan specificerer jeg uml namespace?

jeg har prøvet følgende:

    protected static XPath getXpathNamespace(){
        XPathFactory factory = XPathFactory.newInstance 
                ();
        XPath xpath = factory.newXPath();
        xpath.setNamespaceContext(
                new NamespaceContextMap(new 
                                          String[]
                        {   
                            "uml","//omg.org/UML1.3"
                        }));
        return xpath;
    }

og i main

XPath xPath = getXpathNamespace();
            xPath = XPathFactory.newInstance
                                ().newXPath();
NodeList XMIcontent = (NodeList) xPath.evaluate("//XMI/XMI.Content/UML:Model",doc.getDocumentElement(), XPathConstants.NODESET);

jeg har mit "namespace" fra et eksport document fra enterprise architect <XMI xmi.version="1.1" xmlns:UML="omg.org/UML1.3" timestamp="2013-06-17 15:04:08">

jeg bruger eclipse og forsøger at skrive mit program i java.
Avatar billede arne_v Ekspert
25. juni 2013 - 01:47 #5
Eksempel:


import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XMIParse {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new InputSource(new FileReader("/work/xmi.xml")));
        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(new NamespaceContext() {
            public String getNamespaceURI(String prefix) {
                if(prefix.equals("UML")) {
                    return "http://org.omg/UML/1.3";
                } else {
                    return null;
                }
            }
            public String getPrefix(String namespace) {
                if(namespace.equals("http://org.omg/UML/1.3")) {
                    return "UML";
                } else {
                    return null;
                }
            }
            public Iterator getPrefixes(String namespace) {
                return null;
            }
        });
        NodeList clzes = (NodeList)xpath.evaluate("//XMI/XMI.content/UML:Model/UML:Namespace.ownedElement/UML:Class", doc.getDocumentElement(), XPathConstants.NODESET);
        for(int i = 0; i < clzes.getLength(); i++) {
            Node clz = clzes.item(i);
            System.out.println(clz.getAttributes().getNamedItem("visibility") + " " + clz.getAttributes().getNamedItem("name"));
        }
    }
}


Noter at jeg har sat http: paa URL:

<XMI xmi.version="1.1" xmlns:UML="http://org.omg/UML/1.3" timestamp="17. juni 2013 14:24:09">

ellers ville XPath ikke acceptere den URL.
Avatar billede HeleneHH Nybegynder
25. juni 2013 - 11:54 #6
Det virker desværre heller ikke. Længden af clzes er 0. Kan der være problemer med namespaced? Jeg har tjekket stien igen. Jeg har bl.a. prøvet at skrive //XMI.content og her finder den en node. Hvis jeg så skriver //XMI.content/UML:Model så finder den ikke noget.
Avatar billede HeleneHH Nybegynder
25. juni 2013 - 14:21 #7
Jeg har også prøvet med http://www.omg.org/spec/UML/1.3/
Avatar billede arne_v Ekspert
26. juni 2013 - 02:34 #8
Jeg testede jo koden inden jeg postede den.

Kan du poste hvordan din kode ser ud nu?
Avatar billede HeleneHH Nybegynder
26. juni 2013 - 08:31 #9
Jeg har prøvet bare at kopiere din kode:

package XMLmodify;

import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class XMLmodify {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new InputSource(new FileReader("P:\\UML\\HHClassTest.xml")));
        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(new NamespaceContext() {
            public String getNamespaceURI(String prefix) {
                if(prefix.equals("UML")) {
                    return "http://org.omg/UML/1.3";
                } else {
                    return null;
                }
            }
            public String getPrefix(String namespace) {
                if(namespace.equals("http://org.omg/UML/1.3")) {
                    return "UML";
                } else {
                    return null;
                }
            }
            public Iterator getPrefixes(String namespace) {
                return null;
            }
        });
        NodeList clzes = (NodeList)xpath.evaluate("//XMI/XMI.content/UML:Model", doc.getDocumentElement(), XPathConstants.NODESET);
       
        System.out.println(clzes.getLength());
        for(int i = 0; i < clzes.getLength(); i++) {
            Node clz = clzes.item(i);
            System.out.println(clz.getAttributes().getNamedItem("visibility") + " " + clz.getAttributes().getNamedItem("name"));
        }
        System.out.println("done");
    }
}


og det virker desværre heller ikke.
Dette er mit prøve .xml dokument (HHClassTest.xml):


<?xml version="1.0" encoding="UTF-8"?>
<XMI xmi.version="1.1" xmlns:UML="//org.omg/UML/1.3" timestamp="17. juni 2013 14:24:09">
  <XMI.header>
    <XMI.documentation>
      <XMI.exporter>
      </XMI.exporter>
      <XMI.exporterVersion>
      </XMI.exporterVersion>
    </XMI.documentation>
    <XMI.metamodel xmi.name="UML" xmi.version="1.4">
    </XMI.metamodel>
  </XMI.header>
  <XMI.content>
    <UML:Model name="rhapsody_test" visibility="public" 
    xmi.id="ML1">
    </UML:Model>
  </XMI.content>
</XMI>
Avatar billede arne_v Ekspert
27. juni 2013 - 03:22 #10
Du har ikke rettet namespace rigtigt til.

Java koden bruger:

http://org.omg/...

XML bruger:

//org.omg/UML/1.3

De skal vaere ens!
Avatar billede HeleneHH Nybegynder
27. juni 2013 - 10:25 #11
Hej Arne, hvis du putter curseren hen over http://org.omg/(...) i min kode, så vil du se at der står http://org.omg/UML/1.3 (og det er det der skal stå, ik? ellers forstår jeg muligvis ikke helt dit svar :))
I din kode vil du se at der også stå http://org.omg/(...) selvom du faktisk har skrevet http://org.omg/UML/1.3.
Avatar billede HeleneHH Nybegynder
27. juni 2013 - 10:27 #12
Hej Arne, hvis du putter curseren hen over http://org.omg/(...) 

i min kode, så vil du se at der står http://org.omg/UML/1.3

(og det er det der skal stå, ik? ellers forstår jeg muligvis ikke helt dit svar :))
I din kode vil du se at der også stå http://org.omg/(...) selvom du faktisk har skrevet http://org.omg/UML/1.3.
Avatar billede arne_v Ekspert
27. juni 2013 - 15:53 #13
Du bruger uden "http:" i XML og med "http:" i Java koden. Det duer ikke.
Avatar billede HeleneHH Nybegynder
27. juni 2013 - 15:59 #14
ah, ok... det ¨må jeg lige prøve. Jeg har nu også fået det løst således:

NodeList orgDiagramNodeList = (NodeList)xPath.evaluate("//*[local-name()='Model']",doc.getDocumentElement(), XPathConstants.NODESET);

hvilket jeg fik tippet til her:
http://stackoverflow.com/questions/15139979/select-node-without-namespace-with-xpath

Tusind tak for hjælpen :)
Avatar billede arne_v Ekspert
28. juni 2013 - 00:28 #15
Det er et workaround som virker saa laenge du ikke har flere elemeneter med samme local name men forskellig namespace.
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