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>

    <ch3/>
    </a1>

    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/>
    </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





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.