문제

수신 비누 메시지가있는 형식이 tstream (delphi7),이 비누를 보내는 서버는 개발 모드에 있으며 디버깅 목적으로 메시지에 HTML 헤더를 추가합니다. 이제 HTML 헤더 부품을 SOAP 변환기로 전달하기 전에 HTML 헤더 부품을 잘라야합니다. 처음부터 'pre'태그로 시작하여 '/pre'태그로 끝납니다. 나는 그것이 매우 쉬워야한다고 생각하지만 Delphi7에서 전에 그것을하지 않았으니 누군가 나를 도울 수 있습니까?

도움이 되었습니까?

해결책

나는 당신이 하나만 있다고 가정하면 다음 코드가 당신이 원하는 것을 할 것이라고 생각합니다.u003Cpre> 문서의 차단.

function DepreStream(Stm : tStream):tStream;
var
  sTemp : String;
  oStrStm : tStringStream;
  i : integer;
begin
  oStrStm := tStringStream.create('');
  try
    Stm.Seek(0,soFromBeginning);
    oStrStm.copyfrom(Stm,Stm.Size);
    sTemp := oStrStm.DataString;
    if (Pos('<pre>',sTemp) > 0) and (Pos('</pre>',sTemp) > 0) then
      begin
        delete(sTemp,Pos('<pre>',sTemp),(Pos('</pre>',sTemp)-Pos('<pre>',sTemp))+6);
        oStrStm.free;
        oStrStm := tStringStream.Create(sTemp);
      end;
    Result := tMemoryStream.create;
    oStrStm.Seek(0,soFromBeginning);
    Result.CopyFrom(oStrStm,oStrStm.Size);
    Result.Seek(0,soFromBeginning);
  finally
    oStrStm.free;
  end;
end;

또 다른 옵션은 XML 변환을 사용하여 원치 않는 태그를 제거하는 것이지만 다른 사람이 그 횃불을 원한다면 변환 방식을 많이하지 않습니다 ...

편집하다: 작동하도록 수정 된 코드. 먼저 IDE가 아닌 직접 코딩을 가르쳐줍니다.

다른 팁

LARS의 제안에 따라 더 많은 해결책을 제시하고 더 많은 해결책이 해결되었습니다.
특히 스트림의 크기가 100 이상이고 실제로 큰 것들에서는 더 빠릅니다. 중간 문자열에 복사하지 않습니다.
FilterBeginStream 더 단순하고 헤더가 끝날 때까지 모든 것을 제거 할 때 "사양"을 따릅니다.
FiltermIddlestream 헤더 전후의 내용을 남기고 감가 상각과 동일합니다.

경고:이 코드는 D2009가 아니라 D2007까지 Delphi에 대한 것입니다.

// returns position of a string token (its 1st char) into a Stream. 0 if not found
function StreamPos(Token: string; AStream: TStream): Int64;
var
  TokenLength: Integer;
  StringToMatch: string;
begin
  Result := 0;
  TokenLength := Length(Token);
  if TokenLength > 0 then
  begin
    SetLength(StringToMatch, TokenLength);
    while AStream.Read(StringToMatch[1], 1) > 0 do
    begin
      if (StringToMatch[1] = Token[1]) and
         ((TokenLength = 1) or
          ((AStream.Read(StringToMatch[2], Length(Token)-1) = Length(Token)-1) and
           (Token = StringToMatch))) then
      begin
        Result := AStream.Seek(0, soCurrent) - (Length(Token) - 1); // i.e. AStream.Position - (Length(Token) - 1);
        Break;
      end;
    end;
  end;
end;

// Returns portion of a stream after the end of a tag delimited header. Works for 1st header.
// Everything preceding the header is removed too. Returns same stream if no valid header detected.
// Result is True if valid header found and stream has been filtered.
function FilterBeginStream(const AStartTag, AEndTag: string; const AStreamIn, AStreamOut: TStream): Boolean;
begin
  AStreamIn.Seek(0, soBeginning); // i.e. AStreamIn.Position := 0;
  Result := (StreamPos(AStartTag, TStream(AStreamIn)) > 0) and (StreamPos(AEndTag, AStreamIn) > 0);
  if Result then
    AStreamOut.CopyFrom(AStreamIn, AStreamIn.Size - AStreamIn.Position)
  else
    AStreamOut.CopyFrom(AStreamIn, 0);
end;

// Returns a stream after removal of a tag delimited portion. Works for 1st encountered tag.
// Returns same stream if no valid tag detected.
// Result is True if valid tag found and stream has been filtered.
function FilterMiddleStream(const AStartTag, AEndTag: string; const AStreamIn, AStreamOut: TStream): Boolean;
var
  StartPos, EndPos: Int64;
begin
  Result := False;
  AStreamIn.Seek(0, soBeginning); // i.e. AStreamIn.Position := 0;
  StartPos := StreamPos(AStartTag, TStream(AStreamIn));
  if StartPos > 0 then
  begin
    EndPos := StreamPos(AEndTag, AStreamIn);
    Result := EndPos > 0;
  end;
  if Result then
  begin
    if StartPos > 1 then
    begin
      AStreamIn.Seek(0, soBeginning); // i.e. AStreamIn.Position := 0;
      AStreamOut.CopyFrom(AStreamIn, StartPos - 1);
      AStreamIn.Seek(EndPos - StartPos + Length(AEndTag), soCurrent);
    end;
    AStreamOut.CopyFrom(AStreamIn, AStreamIn.Size - AStreamIn.Position);
  end
  else
    AStreamOut.CopyFrom(AStreamIn, 0);
end;

TSTREAM.COPYFROM 또는 TSTREAM.READBUFFER/WRITEBUFFER 메소드를 사용하여 새 TSTREAM (TMEMORYSTREAM 사용)을 만들고 한 스트림에서 다른 스트림으로 유지하려는 물건을 이동하십시오.

"XPath 표현"//pre[1][1]"첫 번째 노드를 운반 할 것입니다.u003Cpre> XML 메시지의 태그 : 설명에서 원하는 비누 메시지가 포함되어야합니다.

마지막으로 사용한 지 몇 년이 지났지 만 Dieter Koehler의 OpenXML 라이브러리 XPath를 지원합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top