Einzelnen Beitrag anzeigen

Neuromancer

Registriert seit: 8. Aug 2003
62 Beiträge
 
Delphi 7 Enterprise
 

Re: XML: Namespace - Zuweisung funktioniert nicht

  Alt 22. Mai 2006, 17:33
So, ich habe es endlich gefunden...

Zitat von msdn:
One other XPath enhancement that you can expect sometime soon has to do with proper namespace support. According to the XPath specification, when expressions contain unqualified element names (no namespace prefix), the elements are considered part of no namespace (even if a default namespace declaration is present in the source document). When XPath expressions contain qualified names (through a namespace prefix) they are evaluated according to the namespace bindings that make up the current XPath context. However, there is currently no mechanism in place for establishing namespace bindings prior to evaluating an XPath expression in MSXML 3.0. This makes it impossible to properly query namespace-aware XML documents.
For example, assuming the following XML document:

<foo xmlns='urn:foo-bar:baz'>
<bar><baz/></bar>
</foo>

what should be returned by the /foo/bar/baz expression? According to the XPath specification, it should return nothing because it's looking for foo, bar, and baz elements that belong to no namespace. But in the source document the foo, bar, and baz elements all belong to the urn:foo-bar:baz namespace.
To solve this problem, in a future release of MSXML 3.0 it will be possible to specify namespace bindings through the SelectionNamespaces property before calling selectNodes, as shown here:

doc.setProperty "SelectionNamespaces", _
"xmlns:f='urn:foo-bar:baz'"
set sel = doc.selectNodes("/f:foo/f:bar/f:baz")

With the namespace bindings in place, this expression should now behave properly because it identifies foo, bar, and baz elements that belong to the 'urn:foo-bar:baz', which matches the default namespace declaration in the source document. (Note that syntax may change by release time.)
In der Praxis ergibt sich daraus folgendes:

Ich habe Saschas xml-Datei mal so "validiert":
XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
   <Document>
      <Folder>
         <name>My Places</name>
         <open>1</open>
         <Folder>
            <name>Ordner1</name>
            <open>1</open>
            <Placemark>
               <name>Placemark1</name>
               <LookAt>
                  <longitude>10.37993318693747</longitude>
                  <latitude>19.35357660723419</latitude>
                  <range>743945.2733547823</range>
                  <tilt>-1.858292979523515e-013</tilt>
                  <heading>1.206473994247129</heading>
               </LookAt>
               <styleUrl>root://styleMaps#default+nicon=0x307+h
icon=0x317</styleUrl>
               <Point>
                  <coordinates>10.37993318693747,19.35357660723419
,0</coordinates>
               </Point>
            </Placemark>
         </Folder>
      </Folder>
   </Document>
</kml>
Dann funktioniert folgender Code nicht:
Delphi-Quellcode:
procedure TForm1.btnGoClick(Sender: TObject);
var
  aXMLDoc: IXMLDOMDocument2;
  aXMLNode: IXMLDOMNode;
begin
  aXMLDoc := CoDOMDocument40.Create;
  aXMLDoc.setProperty('NewParser', true);
  aXMLDoc.setProperty('SelectionLanguage', 'XPath');

  if not aXMLDoc.loadXML(me1.Text) then
    raise Exception.Create('shyce war''s beim Laden des XML-Dokuments!');

  aXMLDoc.save('test.xml');

  aXMLNode := aXMLDoc.selectSingleNode('kml');

  if aXMLNode = nil then
     raise Exception.Create('kein Knoten gefunden!');

  ShowMessage(aXMLNode.xml);
end;
...und die Exception wird geworfen.

Bringe ich dem Parser aber bei, was M$ fordert, dann funktioniert der Code:

Delphi-Quellcode:
procedure TForm1.btnGoClick(Sender: TObject);
var
  aXMLDoc: IXMLDOMDocument2;
  aXMLNode: IXMLDOMNode;
begin
  aXMLDoc := CoDOMDocument40.Create;
  aXMLDoc.setProperty('NewParser', true);
  aXMLDoc.setProperty('SelectionLanguage', 'XPath');
  // !!!
  aXMLDoc.setProperty('SelectionNamespaces', 'xmlns:DNS="http://earth.google.com/kml/2.0"');

  if not aXMLDoc.loadXML(me1.Text) then
    raise Exception.Create('shyce war''s beim Laden des XML-Dokuments!');

  aXMLDoc.save('test.xml');

  aXMLNode := aXMLDoc.selectSingleNode('DNS:kml'); // !!!

  if aXMLNode = nil then
     raise Exception.Create('kein Knoten gefunden!');

  ShowMessage(aXMLNode.xml);
end;
Ich hoffe, ich habe jetzt nicht noch mehr Verwirrung, sondern Aufklärung gestiftet...

Gruß
  Mit Zitat antworten Zitat