【问题标题】:Input XML data doen't match with the output XML format输入 XML 数据与输出 XML 格式不匹配
【发布时间】:2012-10-30 08:46:28
【问题描述】:

输入 XML

<?xml version="1.0" encoding="utf-8"?>
<!--00/00/0000 12:35:25 AM-->
<Physical xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
  <Pro managementID="22000020">
    <Identification Type="XXXXX" >          
      <Address>
        <Data>test</Data>        
      </Address>
      <Phone>
        <Number>0000</Number>
      </Phone>
      <Email>test@com</Email>
    </Identification>       
  </Pro>
</Physical>

脚本:

我正在尝试更改标记的值并将其余部分打印到新的输出 xml 文件中

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;     

  my $xml = XML::Simple->new(ForceContent => 1,);
  my $xmlData = $xml->XMLin('input.xml') or die$!;     

  print Dumper (\$xmlData);

  foreach my $xmlKey ( keys %{$xmlData} ){
   if ( $xmlKey =~ m/Pro/){
       print ${$xmlData}{$xmlKey}{Identification}{Address}{Data}="hello";
    }
  }

XMLout(
    $xmlData,
    KeepRoot => 1,
    NoAttr => 0,
    OutputFile => $xml_out,
);

输出 XML:

<opt xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Pro managementID="22000020">
     <Identification Type="XXXXX">
      <Address Data="hello" />
      <Email>test@com</Email>
      <Phone name="Number">0000</Phone>
    </Identification>
  </Pro>
</opt>

我可以更改值,但我试图将数据写入输出格式已更改。任何人都可以指导我获取相同的输入数据,更改值作为输出。

【问题讨论】:

  • 这就是为什么您不使用 XML::Simple 进行输出。

标签: xml perl


【解决方案1】:

以这种方式使用 XML::LibXML:

#!/usr/bin/perl
use strict;
use warnings;

use XML::LibXML;

my $input;
while(<>) {
    $input .= $_;
}
my $xml_doc = XML::LibXML->load_xml(string => $input);
my $xpath_ctx = new XML::LibXML::XPathContext($xml_doc);
$xpath_ctx->find("/Physical/Pro/Identification/Address/Data")->get_node(0)->firstChild()->setData("hello");
my $xml_data = $xpath_ctx->find("/")->get_node(0)->toString(1);

print $xml_data;

XML::LibXML 速度更快,并且在 XPath 的帮助下,$xml_doc 的操作更容易。

更多信息你可以找到here

【讨论】:

  • 你为什么不用load_xml( location =&gt; 'input.xml' )
  • @choroba 没有任何理由......你可以随心所欲地使用它
  • @choroba nahh ...两种方式都很简单...取决于您要做什么
  • @memosdp:除非您出于其他目的需要这样做,否则将整个文件读入内存确实是错误的。显然并不像提供对load_xml的调用的文件路径那样简单。
  • @Borodin 我同意......大文件应该是一个问题,而且我不太相信 perl 的内存处理......但实际问题与这个……我只是复制了OP提供的xml,我举了一个快速的例子……就是这样。我的意思是我没有编写代码来有效地处理 xml 文档的源,而只是为了说明 LibXML 的用法。如何处理 xml 文档的源代码,取决于您要对要实现的整个接口做什么。
【解决方案2】:

使用不同的 XML 处理模块。例如,此脚本使用 XML::XSH2,它是 XML::LibXML 的包装器:

#!/usr/bin/perl
use warnings;
use strict;

use XML::XSH2;

xsh << 'END';
    open input.xml ;
    for //*[xsh:matches(name(),'Pro')]/Identification/Address/Data
        set . 'hello' ;
    save :b ;
END

【讨论】:

    【解决方案3】:

    一个 XML::Twig 版本:

    #!/usr/bin/perl 
    
    use strict;
    use warnings;
    
    use XML::Twig;
    
    XML::Twig->new( twig_roots => { 'Pro/Identification/Address/Data' => sub { $_->set_text( 'hello'); $_->flush; } },
                    twig_print_outside_roots => 1,
                  )
             ->parsefile( 'input.xml');
    

    【讨论】:

      【解决方案4】:

      使用 XML::Rules 的另一种方式

      use strict;
      use warnings;
      
      use XML::Rules;
      
      my @rules = (
        Data => sub { $_[1]{_content} =~ s/test/hello/; return $_[0] => $_[1] },
      );
      my $xr = XML::Rules->new(
        rules => \@rules,
        style => 'filter',
      );
      
      $xr->filterfile('input.xml');
      

      【讨论】:

        【解决方案5】:

        您已将 NoAttr 设置为输出为零。

        这不是和你想要的相反吗?

        NoAttr => 1

        当与 XMLout() 一起使用时,生成的 XML 将不包含任何属性。 所有哈希键/值都将表示为嵌套元素。

        NoAttr 会停止

        <Phone>
            <Number>0000</Number>
        

        变成

         <Phone name="Number">
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多