如何使用cl_xslt_处理器解析具有名称空间的XML文档?

如何使用cl_xslt_处理器解析具有名称空间的XML文档?,xml,abap,Xml,Abap,我有以下XML 1 2 3 4 5 6 这个XML被压缩成XSTRING。从这个XSTRING中,我想检索我想要的所有节点,例如NominaIndividual/Devengados/Anticipos 到目前为止,我可以用下面的代码成功地完成这项工作,但前提是我必须从NominaIndividual中完全删除所有名称空间: DATA lo_xslt TYPE REF TO cl_xslt_processor. DATA lo_nodes TYPE REF TO if_ix

我有以下
XML


1
2
3
4
5
6
这个
XML
被压缩成
XSTRING
。从这个
XSTRING
中,我想检索我想要的所有节点,例如
NominaIndividual/Devengados/Anticipos

到目前为止,我可以用下面的代码成功地完成这项工作,但前提是我必须从
NominaIndividual
中完全删除所有名称空间:

    DATA lo_xslt  TYPE REF TO cl_xslt_processor.
    DATA lo_nodes TYPE REF TO if_ixml_node_collection.

     CREATE OBJECT lo_xslt.

    lo_xslt->set_source_xstring( iv_xml ).

    lo_xslt->set_expression( '//Devengados/Anticipos/Anticipo').  
    lo_xslt->run( '' ).

    lo_nodes    = lo_xslt->get_nodes( ).
    ro_iterator = lo_nodes->create_iterator( ).
    ro_node     = ro_iterator->get_next( ).
在这段代码中,最后一个对象
ro_节点
包含我需要的所有信息。但问题是:只有从
nominainidividual
中完全删除所有名称空间,才能创建此对象:

    DATA lo_xslt  TYPE REF TO cl_xslt_processor.
    DATA lo_nodes TYPE REF TO if_ixml_node_collection.

     CREATE OBJECT lo_xslt.

    lo_xslt->set_source_xstring( iv_xml ).

    lo_xslt->set_expression( '//Devengados/Anticipos/Anticipo').  
    lo_xslt->run( '' ).

    lo_nodes    = lo_xslt->get_nodes( ).
    ro_iterator = lo_nodes->create_iterator( ).
    ro_node     = ro_iterator->get_next( ).
例如,如果我将XML修改为:


...
但是,这是原始XML,它不是:


...

也就是说,如何通过
XPATH
维护名称空间来浏览XML树?我知道方法
cl\u xslt\u processor->set\u expression
有一个关于名称空间的参数,但我不知道如何正确使用ir。

可以对父元素使用通配符,如下所示:

DATA(l_xslt) = new cl_xslt_processor( ).

l_xslt->set_source_string(
` <?xml version="1.0" encoding="UTF-8"?> ` &&
` <NominaIndividual xmlns="dian:gov:co:facturaelectronica:NominaIndividual" ` &&
`                   xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" ` &&
`                   xmlns:ds="http://www.w3.org/2000/09/xmldsig#" ` &&
...
`         </Anticipos>  ` &&
`    </Deducciones>  ` &&
` </NominaIndividual> ` ).

l_xslt->set_expression( expression = '//*[local-name()="Anticipo"]' ).
l_xslt->run( '' ).
DATA(nodes) = l_xslt->get_nodes( ).

DO nodes->get_length( ) TIMES.
  DATA(node) = nodes->get_item( sy-index - 1 ).
  WRITE node->get_value( ).
ENDDO.
最后,不要使用它。它是(第24页),使用XSLT转换代替


要使用名称空间,方法
SET\u EXPRESSION
具有参数
nsdeclarations
,用于将参数
表达式中使用的名称空间前缀映射到实际的名称空间URI。我扩展了答案,为
Devengados
添加了一个额外的名称空间
演示:URI
,以演示如何指示多个名称空间。注意,根据XML标准,名称空间前缀可以是任何内容,重要的是名称空间URI

  DATA(iv_xml) =
  ` <?xml version="1.0" encoding="UTF-8"?> ` &&
  ` <NominaIndividual xmlns="dian:gov:co:facturaelectronica:NominaIndividual" ` &&
  `                   xmlns:demo="demonstration:URI" ` &&
  `                   xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" ` &&
  `                   xmlns:ds="http://www.w3.org/2000/09/xmldsig#">` &&
  `    <demo:Devengados>` &&
  `        <Anticipos>` &&
  `            <Anticipo>1.00</Anticipo>` &&
  `            <Anticipo>2.00</Anticipo>` &&
  `            <Anticipo>3.00</Anticipo>` &&
  `        </Anticipos>` &&
  `    </demo:Devengados>` &&
  ` </NominaIndividual> `.

  DATA(xml_utf8) = cl_abap_codepage=>convert_to( iv_xml ).

  DATA lo_xslt  TYPE REF TO cl_xslt_processor.
  DATA lo_nodes TYPE REF TO if_ixml_node_collection.

  CREATE OBJECT lo_xslt.

  lo_xslt->set_source_xstring( xml_utf8 ).

  lo_xslt->set_expression(
              expression     = `//pp:Devengados/dd:Anticipos/dd:Anticipo`
              nsdeclarations = `pp demonstration:URI `
                            && `dd dian:gov:co:facturaelectronica:NominaIndividual` ).
  lo_xslt->run( '' ).

  lo_nodes = lo_xslt->get_nodes( ).
  DO lo_nodes->get_length( ) TIMES.
    WRITE / lo_nodes->get_item( sy-index - 1 )->get_value( ).
  ENDDO.
1.00
2.00
3.00