如何使用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