Menu

OXmlPSeq how to read node text after ReadNextChildElementHeader?

2016-05-05
2016-05-16
  • Grigoriy Poverenniy

    OXmlPSeq how to read node text after ReadNextChildElementHeader?

     
  • Grigoriy Poverenniy

    Add this patch. WhiteSpace and null text can cause problems, but in my test files 300-1000 gb error was not found.

    Index: OXmlPSeq.pas
    ===================================================================
    --- OXmlPSeq.pas    (revision 129)
    +++ OXmlPSeq.pas    (working copy)
    @@ -385,6 +385,38 @@
     var
       xLastNode: PXMLNode;
       xBreakReading: TXMLBreakReading;
    +  text: string;
    +
    +  procedure ReadTextContent();
    +  begin
    +    text := '';
    +    try
    +    while fReader.ReadNextToken(fReaderToken) do
    +        begin
    +          case fReaderToken.TokenType of
    +            rtOpenElement:
    +            begin
    +              Break;
    +            end;
    +            rtText: begin
    +              if (text = '') and (OXmlIsWhiteSpace(fReaderToken.TokenValue)) then Continue;
    +              text := text + fReaderToken.TokenValue;
    +              break;
    +            end;
    +
    +            rtFinishOpenElementClose,
    +            rtCloseElement:
    +              Exit;
    +          end;
    +        end;
    +    finally
    +      if text <> '' then
    +      begin
    +        xLastNode.NodeValue := text;
    +      end;
    +    end;
    +
    +  end;
     begin
       Result := False;
       fParseError := nil;
    @@ -414,6 +446,10 @@
                   xLastNode := fXmlDoc.Node.AddChild(fReaderToken.TokenName);
                   Break;
                 end;
    +            rtText: begin
    +
    +            end;
    +
                 rtCloseElement://parent element may be closed
                   Exit;
               end;
    @@ -447,9 +483,11 @@
               begin
                 outElementIsOpen := True;
                 Result := True;
    +            ReadTextContent;
                 Exit;
               end;
    -          rtFinishXMLDeclarationClose, rtFinishOpenElementClose, rtCloseElement:
    +          rtFinishXMLDeclarationClose,
    +            rtFinishOpenElementClose, rtCloseElement:
               begin
                 outElementIsOpen := False;
                 Result := True;
    
     
  • Grigoriy Poverenniy

    Next patch.

    Index: OXmlPSeq.pas
    ===================================================================
    --- OXmlPSeq.pas    (revision 129)
    +++ OXmlPSeq.pas    (working copy)
    @@ -385,6 +385,47 @@
     var
       xLastNode: PXMLNode;
       xBreakReading: TXMLBreakReading;
    +  text: string;
    +
    +  function ReadTextContent(var ANotCloseElement: Boolean): Boolean;
    +  begin
    +    text := '';
    +    ANotCloseElement := True;
    +    try
    +    while fReader.ReadNextToken(fReaderToken) do
    +        begin
    +          case fReaderToken.TokenType of
    +            rtOpenElement:
    +            begin
    +              Break;
    +            end;
    +            rtText: begin
    +              //if (text = '') and (OXmlIsWhiteSpace(fReaderToken.TokenValue)) then Continue;
    +              text := fReaderToken.TokenValue;
    +              Result := True;
    +              break;
    +            end;
    +            rtCloseElement:
    +            begin
    +              ANotCloseElement := False;
    +              Result := False;
    +              break;
    +            end;
    +            rtFinishOpenElementClose:
    +            begin
    +              Result := False;
    +              break;
    +            end;
    +          end;
    +        end;
    +    finally
    +      if text <> '' then
    +      begin
    +        xLastNode.NodeValue := text;
    +      end;
    +    end;
    +
    +  end;
     begin
       Result := False;
       fParseError := nil;
    @@ -398,8 +439,13 @@
         begin
           //last found was opening element (most probably from GoToPath()), write it down!
           xLastNode := fXmlDoc.Node.AddChild(fReaderToken.TokenName)
    -    end else
    +    end
    +     {else if Assigned(fReaderToken) and (fReaderToken.TokenType = rtCloseElement) then
         begin
    +      fReader.ReadNextToken(fReaderToken);
    +    end}
    +    else
    +    begin
           //last found was something else
           xLastNode := fXmlDoc.Node;
    
    @@ -414,6 +460,10 @@
                   xLastNode := fXmlDoc.Node.AddChild(fReaderToken.TokenName);
                   Break;
                 end;
    +            rtText: begin
    +
    +            end;
    +
                 rtCloseElement://parent element may be closed
                   Exit;
               end;
    @@ -447,9 +497,11 @@
               begin
                 outElementIsOpen := True;
                 Result := True;
    +            ReadTextContent(outElementIsOpen);
                 Exit;
               end;
    -          rtFinishXMLDeclarationClose, rtFinishOpenElementClose, rtCloseElement:
    +          rtFinishXMLDeclarationClose,
    +            rtFinishOpenElementClose, rtCloseElement:
               begin
                 outElementIsOpen := False;
                 Result := True;
    
     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-14

    Do you have a test application to see what you want to achieve?

     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-14

    Your patches are wrong.

    Use TXMLSeqParser.ReadNextChildNode after ReadNextChildElementHeader as demonstrated in unit tests function TOXmlUnitTest. Test_OXmlPSeq_TXMLSeqParser_Test2.

     
  • Grigoriy Poverenniy

    ReadNextChildNode read all sub Child nodes. This no good...

     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-16

    Then use ReadNextChildHeader from r130.

     
  • Grigoriy Poverenniy

    <a1>
    <ch1>xcxcxcxc</ch1>
    <ch2 a="v"></ch2></a1>

    <ch3>
    </ch3>

    This source not read "xcxcxcxc" value.

    I understand the complexity of the problem in this situation. It is necessary to read the following tag and come back. How to do it is not clear ...

     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-16

    Use ReadNextChildHeader again.

     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-16

    and come back

    Use GoToPath('..')

     
  • Grigoriy Poverenniy

    ... how to read "value" - "xcxcxcxc"

    <a1> <ch1>xcxcxcxc</ch1> <ch2 a="v"></ch2>
    <ch3>
    </ch3></a1>

    use ReadNextChildHeader,without ReadNextChildNode?

     
  • Ondrej Pokorny

    Ondrej Pokorny - 2016-05-16

    Yes.

    Do you have a commercial license for OXml?
    If you want me to write the code for you, I can do that. In this case please contact me through email (contact at www.kluug.net/legal.php)

     
  • Grigoriy Poverenniy

    Sorry.... ReadNextChildHeader - this is work, not ReadNextChildElementHeader. I do not rush to get a grasp ... In the near future to purchase a license.

     

Anonymous
Anonymous

Add attachments
Cancel