Browse Source

* When reading XML with namespace processing enabled, create 'level 2' elements and attributes even if their namespaceUri is empty.
* dom.pp: fix bug uncovered by above change. Non-empty prefix cannot be set not only for 'level 1' nodes, but for level 2 nodes with empty namespaceUri, too.
- xmlwrite.pp: workaround for parser behavior no longer necessary, removed.

git-svn-id: trunk@24315 -

sergei 12 years ago
parent
commit
4b8953c4f9

+ 1 - 1
packages/fcl-xml/src/dom.pp

@@ -2731,7 +2731,7 @@ begin
   if not IsXmlName(Value) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'Node.SetPrefix');
 
-  if (Pos(WideChar(':'), Value) > 0) or not (nfLevel2 in FFlags) or
+  if (Pos(WideChar(':'), Value) > 0) or ((FNSI.NSIndex = 0) and (Value <> '')) or
     ((Value = 'xml') and (FNSI.NSIndex <> 1)) or
     ((ClassType = TDOMAttr) and  // BAD!
     ((Value = 'xmlns') and (FNSI.NSIndex <> 2)) or (FNSI.QName^.Key = 'xmlns')) then

+ 11 - 2
packages/fcl-xml/src/xmltextreader.pp

@@ -119,6 +119,7 @@ type
 
     FNSHelper: TNSSupport;
     FNsAttHash: TDblHashArray;
+    FEmptyStr: PHashItem;
     FStdPrefix_xml: PHashItem;
     FStdPrefix_xmlns: PHashItem;
     FStdUri_xml: PHashItem;
@@ -1226,6 +1227,7 @@ begin
   FValidatorNesting := 0;
   FCurrNode := @FNodeStack[0];
   FCurrAttrIndex := -1;
+  FEmptyStr := FNameTable.FindOrAdd('');
   if FNamespaces then
   begin
     FNSHelper := TNSSupport.Create(FNameTable);
@@ -3622,7 +3624,9 @@ begin
             begin
               attrData^.FPrefix := FNSHelper.GetPrefix(PWideChar(attrData^.FQName^.Key), attrData^.FColonPos);
               Inc(FPrefixedAttrs);
-            end;
+            end
+            else
+              attrData^.FNsUri := FEmptyStr;
           end;
         end;
       end;
@@ -3670,8 +3674,13 @@ begin
   for I := 1 to FAttrCount do
   begin
     attrData := @FNodeStack[FNesting+i];
-    if (attrData^.FColonPos < 1) or Assigned(attrData^.FNsUri) then
+    if Assigned(attrData^.FNsUri) then
       Continue;
+    if (attrData^.FColonPos < 1) then
+    begin
+      attrData^.FNsUri := FEmptyStr;
+      Continue;
+    end;
 
     Pfx := attrData^.FPrefix;
     b := TBinding(Pfx^.Data);

+ 2 - 0
packages/fcl-xml/src/xmlutils.pp

@@ -740,6 +740,8 @@ begin
 
   { provide implicit binding for the 'xml' prefix }
   DefineBinding('xml', stduri_xml, b);
+  { bind default namespace to empty string }
+  DefineBinding('', '', b);
 end;
 
 destructor TNSSupport.Destroy;

+ 1 - 13
packages/fcl-xml/src/xmlwrite.pp

@@ -481,22 +481,10 @@ function SortAtts(Item1, Item2: Pointer): Integer;
 var
   p1: PAttrFixup absolute Item1;
   p2: PAttrFixup absolute Item2;
-  s1, s2: DOMString;
 begin
   Result := Compare(p1^.Attr.namespaceURI, p2^.Attr.namespaceURI);
   if Result = 0 then
-  begin
-    // TODO: Must fix the parser so it doesn't produce Level 1 attributes
-    if nfLevel2 in p1^.Attr.Flags then
-      s1 := p1^.Attr.localName
-    else
-      s1 := p1^.Attr.nodeName;
-    if nfLevel2 in p2^.Attr.Flags then
-      s2 := p2^.Attr.localName
-    else
-      s2 := p2^.Attr.nodeName;
-    Result := Compare(s1, s2);
-  end;
+    Result := Compare(p1^.Attr.localName, p2^.Attr.localName);
 end;
 
 procedure TXMLWriter.NamespaceFixup(Element: TDOMElement);