2021년의 Perl과 XML: 경험과 교훈

10538 단어 xmlworkprogrammingperl
나는 이미 여러 해 동안 XML와 관련된 어떤 것도 시도해 본 적이 없지만, 최근의 한 프로젝트는 나로 하여금 90년대 문서 양식을 생성, 해석, 수정하는 일에 다시 한 번 몰입하게 했다.현재 대부분의 개발자들은 웹 브라우저에서 이름이 이상한 XMLHTTPRequest 대상의 일부분으로 서버 검색 JSON 형식의 데이터와 AJAX 의 'X' 에 사용되는 것만 알 수 있다.하지만 2021년에도 여전히 많은 API와 문서가 XML을 사용해 작업을 완성하고 있다.
특수한 경우, 작업은 Virtuozzo Automator 의 새 버전을 업데이트하기 위해 API를 호출하는 것입니다.그것의 API는 HTTP 를 사용하지 않고 서버에 암호화된 플러그인을 열고 TLS 분리된 문서를 교환하는 데 의존하기 때문에 좀 심상치 않다.우리의 코드의 이전 버전은 1990년대의sysadmin 스타일의 Perl입니다. 이것은 null character 수동 bless 처리 대상을 사용하고 XML을 해석합니다.개체 시스템과 적절한 XML 파서를 사용하도록 업데이트하기로 결정했습니다.그런데 어떤 해상도와 모듈을 사용해야 하나요?
regular expressions
파서 선택
Moo에서 XML을 해석하고 생성하는 데 몇 개 가 있는데 각각의 장점과 단점이 있다.내가 말하고 싶은 것은, 나는 그들 모두에게 전면적인 조사를 했지만, 이 프로젝트는 시간이 촉박하다는 것이다. (전부가 아닌가?)Perl 스택에 너무 많은 추가 의존 항목을 만들고 싶지 않습니다.다행히도 generic XML modules는 이미 사용할 수 있다. 나는 이전에 그것을 사용한 경험이 있다. 성능 표준을 바탕으로 하는 XML 해석CPAN이나 XML::LibXML을 사용하고 생성하는 것은 좋은 선택이다.
의존항을 추가하는 데 더 많은 시간과 여유가 있다면 다른 방법을 사용할 수도 있습니다.만약 Virtuozzo API가 하나DOM나 사용SAX된다면 나는 XML Schema할 것이다. 왜냐하면 나는 다른 프로젝트에서 이미 약간의 성공을 거두었기 때문이다.그래도 막후에서 XML: LibXML을 사용하기 때문에 나는 여전히 그것을 사용할 것이다.너의 이정은 다를 수 있다.
SOAP
XML 생성
생성할 XML 문서의 크기와 복잡성에 따라 XML::Compile 객체를 노드별로 구성할 수 있습니다.Virtuozzo Automator에 보낸 대부분의 메시지는 매우 짧고 삽입하기 쉽기 때문에 Perl 코드에 XML::LibXML::Node개의 XML 고도를 사용했습니다.문서의 예시에 따라 쉽게 검증할 수 있다는 장점도 있다.
메시지의 삽입값이 좀 복잡하면here문서에서 사용합니다XML::LibXML::Element:
@{[...]}
이것은... 부분에 임의의 표현식을 넣고 익명의 그룹 인용에 넣은 다음 문자열 결과에 바로 인용할 수 있도록 합니다.이것은 Perl 문자열에서 최소한의 템플릿화를 할 수 있고 완전한 템플릿 라이브러리를 불러올 필요가 없는 저렴하고 유쾌한 방법이다.데이터베이스 조회를 위한 생성here-document을 할 때 나도 이런 기술을 성공적으로 사용했다.
this idiom
객체 속성의 파서로 사용
나는 문서를 해석해야 하는 모든 방법에서 새로운 SQL 를 실례화하지 않고 개인 속성을 만들었다.
package Local::API::Virtozzo::Agent {
    use Moo;
    use XML::LibXML;
    use Types::Standard qw(InstanceOf);
    ...
    has _parser => (
        is => 'ro',
        isa => InstanceOf['XML::LibXML'],
        default => sub { XML::LibXML->new() },
    );
    sub foo {
        my $self = shift;
        my $send_doc = $self->_parser
          ->parse_string(<<"END_XML");
            <foo/>
END_XML
        ...
    }
...
}

본보기
XML 문서는 지루할 수 있으며, 문서마다 요소가 거의 바뀌지 않습니다.Virtuozzo API에는 요청과 응답을 일치시키는 데 사용되는 요소<packet>가 문서당 하나씩version 있습니다.나는 간단한 함수를 만들어서 내 문서를 이 요소에 포장했다. 이 함수는 버전을 상수에서 끌어내고, 호출할 때마다 id 하나를 증가시켰다.
sub _wrap_packet {
    state $send_id = 1;
    return qq(<packet version="$PACKET_VERSION" id=")
      . $send_id++ . '">' . shift . '</packet>';
}
id 요소에 더 많은 속성을 추가해야 한다면(예를 들어 폐쇄된 요소의 속성 이름 공간) 문서 문자열을 분석한 후에 항상 사용할 수 있다XML::LibXML.

사용XML::LibXML::Element::setAttribute 해석 응답
나는 취약한 정규 표현식을 사용하여 응답에서 데이터를 추출하지 않고 위의 공유 해상도 대상을 사용한 다음에 의 모든 기능을 사용한다.
use English;
...
sub get_sampleID {
    my ($self, $sample_name) = @_;
    ...
    # used to separate documents
    local $INPUT_RECORD_SEPARATOR = "\0";
    # $self->_sock is the IO::Socket::SSL connection
    my $get_doc = $self->_parser( parse_string(
      $self->_sock->getline(),
    ) );
    my $sample_id = $get_doc->findvalue(
        qq(//ns3:id[following-sibling::ns3:name="$sample_name"]),
    );
    return $sample_id;
}
따라서 XPath 모드에서는 요소의 순서가 변경되거나 더 많은 요소가 도입된 경우에도 정확한 데이터를 계속 찾을 수 있습니다.
XPath
결론은... 지금까지.
나는 이 API 호출의 절반 정도만 업데이트했고, 예를 들어 TLS 플러그인 연결 설정 등 XML과 무관한 세부 사항은 생략했다.이 문서가 현재 XML 처리와 관련된 내용을 음미할 수 있기를 바랍니다.만약 어떤 건의나 문제가 있으면 저에게 메시지를 남겨 주세요.

좋은 웹페이지 즐겨찾기