none
EDMX File mittels XPath parsen RRS feed

  • Frage

  • Hallo zusammen

    ich muss ein EDMX File mittels XPath abfragen. Dabei stosse ich auf grosse Probleme !

    Ihr mein Code (ist aus verschiedenen Orten im Code raus kopiert, soll nur andeutungsweise helfen)

        private ModelElements.EntityContainer _container;
        private System.Xml.XmlNamespaceManager _manager;
        
        
        //_manger = XmlNamespaceManager
        
        string xpath = @"/edmx:Edmx/edmx:Runtime/edmx:StorageModels
        
        _manager = new XmlNamespaceManager(nameTable);
        _manager.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");
        _manager.AddNamespace("s", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");
        _manager.AddNamespace("e", "http://schemas.microsoft.com/ado/2007/06/edm");
        _manager.AddNamespace("store", "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator");
        _manager.AddNamespace("u", "urn:schemas-microsoft-com:windows:storage:mapping:SC");
        
        public Dictionary<string, string> parseNode(string xpath, XmlNamespaceManager manager)
        {
          var dicValues = new Dictionary<string, string>();
    
          foreach (XmlNode node in _xmlDoc.SelectNodes(xpath, manager))
          {
            foreach (XmlNode child in node.ChildNodes)
            {
              if (child.Name != "#comment")
                dicValues.Add(child.Name, child.InnerText);
            }
          }
          return dicValues;
        }
    

    Hier bekomme ich noch Nodes im dicValues, wenn ich den XPath nun auf "/edmx:Edmx/edmx:Runtime/edmx:StorageModels/Schema/EntityContainer/EntitySet" erweitere, kommt nichts mehr zurück. Der XPath stimmt aber gemäss XMLSpy ?!

     

    Kann mir da jemand weiterhelfen ?

     

    Gruss
    Peter

    Samstag, 26. März 2011 10:49

Antworten

  • Da findet sich (wie vermutet) ein xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl" beim "Schema"-Element, also muss man dann mit XPath 1.0 einen Präfix verwenden, der an die URL "http://schemas.microsoft.com/ado/2009/02/edm/ssdl" gebunden ist. Wie ich sehe, hast du schon

      _manager.AddNamespace("s", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");

    in deinem Code, also kannst du dann in XPath den Präfix "s" verwenden, also z.B.

      s:Schema/s:EntityContainer/s:EntitySet

    statt Schema/EntityContainer/EntitySet.


    MVP Data Platform Development My blog
    Samstag, 26. März 2011 17:09
  • Der erste Teil deines Pfades, also "/edmx:Edmx/edmx:Runtime/edmx:StorageModels" ist doch korrekt und funktioniert. Du sollst den hinteren Teil abändern, also z.b.

      /edmx:Edmx/edmx:Runtime/edmx:StorageModels/s:Schema/@Namespace

    Beachte, dass ich das Attribut mit Namen "Namespace" selektiere, nicht das Attribut mit Namen "Name", da ein solches in deinem Beispiel nicht existiert.


    MVP Data Platform Development My blog
    Sonntag, 27. März 2011 10:35

Alle Antworten

  • Zeig uns mal einen relevanten Ausschnitt aus dem XML-Dokument. Ich nehme an, es ist ein Problem mit Namensräumen, aber ohne das XML-Dokument zu sehen, kann man nur raten.

    Meist scheitern die Versuche an einer "default namespace declaration" in der Form

      <ein-element xmlns="http://example.com/ns"><kind-element>...</kind-element></ein-element>

    dann muss man mit Microsoft's XPath 1.0 Implementierung für den Namensraum einen Präfix definieren, also z.B.

      _manager.AddNamespace("df", "http://example.com/ns");

    und dann den Präfix in den XPath-Ausdrücken verwenden, um Elemennamen zu qualifizieren, also

      //df:ein-element/df:kind-element

    Prüfe also, ob die Elemente, die du zu selektieren suchst (also Schema/EntityContainer/EntitySet), im Dokument in einem Namensraum definiert sind und verwende dann einen frei wählbaren Präfix, wie oben gezeigt.

    Wenn das nicht weiterhilfe, zeige uns bitte einen relevanten Ausschnitt aus dem Dokument.


    MVP Data Platform Development My blog
    Samstag, 26. März 2011 16:57
  • Hallo Martin

    nun es ist ein normales EDMX File aus dem Entity Framwork 4.1

    <?xml version="1.0" encoding="utf-8"?>
    <edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
    	<!-- EF Runtime content -->
    	<edmx:Runtime>
    		<!-- SSDL content -->
    		<edmx:StorageModels>
    			<Schema Namespace="SISA.PrimaryDomain.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
    				<EntityContainer Name="SISAPrimaryDomainStoreContainer">
    					<EntitySet Name="SISABasicObjectSet" EntityType="SISA.PrimaryDomain.Store.SISABasicObjectSet" store:Type="Tables" Schema="dbo"/>
    					<EntitySet Name="SISABasicObjectSet_SISABusinessObject" EntityType="SISA.PrimaryDomain.Store.SISABasicObjectSet_SISABusinessObject" store:Type="Tables" Schema="dbo"/>
    
    Gruss
    Peter

    Samstag, 26. März 2011 17:03
  • Da findet sich (wie vermutet) ein xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl" beim "Schema"-Element, also muss man dann mit XPath 1.0 einen Präfix verwenden, der an die URL "http://schemas.microsoft.com/ado/2009/02/edm/ssdl" gebunden ist. Wie ich sehe, hast du schon

      _manager.AddNamespace("s", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");

    in deinem Code, also kannst du dann in XPath den Präfix "s" verwenden, also z.B.

      s:Schema/s:EntityContainer/s:EntitySet

    statt Schema/EntityContainer/EntitySet.


    MVP Data Platform Development My blog
    Samstag, 26. März 2011 17:09
  • OK, das habe ich soweit verstanden.

    nun versuche ich aber das Attribut 'Name' des Elementes 'Schema' zu lesen !

    Dieser XPath bringt da keine Nodes zurück '/s:Edmx/s:Runtime/s:StorageModels/Schema' ?!

    Was mache ich nur falsch ?

    Gruss
    Peter

    Sonntag, 27. März 2011 07:58
  • Der erste Teil deines Pfades, also "/edmx:Edmx/edmx:Runtime/edmx:StorageModels" ist doch korrekt und funktioniert. Du sollst den hinteren Teil abändern, also z.b.

      /edmx:Edmx/edmx:Runtime/edmx:StorageModels/s:Schema/@Namespace

    Beachte, dass ich das Attribut mit Namen "Namespace" selektiere, nicht das Attribut mit Namen "Name", da ein solches in deinem Beispiel nicht existiert.


    MVP Data Platform Development My blog
    Sonntag, 27. März 2011 10:35
  • Super !

    Jetzt klappt es - mein Sonntag ist gerettet !

    Danke Dir viel mal für Deine Hilfe :-)

    Gruss
    Peter

    Sonntag, 27. März 2011 11:17