我正在将 XML 文档转换为 HTML。需要做的事情之一是删除命名空间,命名空间不能在 HTML 中合法声明(除非它是根标记中的 XHTML 命名空间)。我发现过 5 到 10 年前的帖子,介绍使用 XML::LibXML 和 LibXML2 来实现这一点有多么困难,但最近没有那么多。这是一个例子:
use XML::LibXML;
use XML::LibXML::XPathContext;
use feature 'say';
my $xml = <<'__EOI__';
<myDoc>
<par xmlns:bar="www.bar.com">
<bar:foo/>
</par>
</myDoc>
__EOI__
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xml);
my $bar_foo = do{
my $xpc = XML::LibXML::XPathContext->new($doc);
$xpc->registerNs('bar', 'www.bar.com');
${ $xpc->findnodes('//bar:foo') }[0];
};
$bar_foo->setNodeName('foo');
$bar_foo->setNamespace('','');
say $bar_foo->nodeName; #prints 'bar:foo'. Dang!
my @namespaces = $doc->findnodes('//namespace::*');
for my $ns (@namespaces){
# $ns->delete; #can't find any such method for namespaces …Run Code Online (Sandbox Code Playgroud) 我试图想出一个perl脚本迭代一些节点并在xml文件中获取值.
我的XML文件如下所示,并保存spec.xml
<?xml version="1.0" encoding="UTF-8"?>
<WO xmlns="http://www.example.com/yyyy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<WOSet>
<SR>
<FINISHTIME>2013-07-29T18:21:38-05:00</FINISHTIME>
<STARTTIME xsi:nil="true" />
<TYPE>SR</TYPE>
<DESCRIPTION>Create CUST</DESCRIPTION>
<EXTERNALSYSTEMID />
<REPORTEDBY>PCAUSR</REPORTEDBY>
<REPORTEDEMAIL />
<STATUS>RESOLVED</STATUS>
<SRID>1001</SRID>
<UID>1</UID>
<SPEC>
<AVALUE>IT</AVALUE>
<ATTRID>CUST_DEPT</ATTRID>
<NALUE xsi:nil="true" />
<TVALUE />
</SPEC>
<SPEC>
<AVALUE>001</AVALUE>
<ATTRID>DEPT_CODE</ATTRID>
<NVALUE xsi:nil="true" />
<TVALUE />
</SPEC>
</SR>
</WOSet>
</WO>
Run Code Online (Sandbox Code Playgroud)
当我运行下面的脚本时,我既没有得到输出也没有任何错误来获得解决问题的地方......
我不是一个perl专家,会喜欢这里的专家通过一些亮点......
#!/usr/bin/perl
use XML::LibXML;
use strict;
use warnings;
my $file = 'spec.xml';
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;
foreach my $atrid ( $tree->findnodes('WO/WOSet/SR/SPEC') ) {
my …Run Code Online (Sandbox Code Playgroud) 尝试按如下方式安装 XML 包时出现错误configure: error: "libxml not found"。看来 R 正在从 Anaconda 获取 libxml2 安装。我怎样才能解决这个问题?
R version 3.4.4 (2018-03-15) -- "Someone to Lean On"\nCopyright (C) 2018 The R Foundation for Statistical Computing\nPlatform: x86_64-pc-linux-gnu (64-bit)\n\n> install.packages("XML")\nInstalling package into \xe2\x80\x98/home/bravegag/R/x86_64-pc-linux-gnu-library/3.4\xe2\x80\x99\n(as \xe2\x80\x98lib\xe2\x80\x99 is unspecified)\ntrying URL \'https://cloud.r-project.org/src/contrib/XML_3.98-1.19.tar.gz\'\nContent type \'application/x-gzip\' length 1600788 bytes (1.5 MB)\n==================================================\ndownloaded 1.5 MB\n\n* installing *source* package \xe2\x80\x98XML\xe2\x80\x99 ...\n** package \xe2\x80\x98XML\xe2\x80\x99 successfully unpacked and MD5 sums checked\nchecking for gcc... gcc\nchecking whether the C compiler works... yes\nchecking for C compiler default output …Run Code Online (Sandbox Code Playgroud) 到目前为止,我发现的唯一示例代码已经很久了,它将不再起作用(使用已弃用的类).我所需要的只是一些基本的东西:
从文件加载和解析XML
定义SAX事件处理程序
读取传递给事件处理程序的元素的属性或文本值
我正在使用XML :: LibXML(Ver:1.70).
我的xml输入文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Equipment xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Equipments>
<ECID logicalName="SysNameAlpha" id="0"/>
<ECID logicalName="SysNameBeta" id="1"/>
</Equipments>
</Equipment>
Run Code Online (Sandbox Code Playgroud)
和我的Perl脚本:
my $file = 'data.xml';
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;
foreach my $camelid ($root->findnodes('Equipments')) {
my $name = $camelid->findvalue('ECID/@logicalName');
my $id = $camelid->findvalue('ECID/@id');
print $name;
print " = ";
print $id;
print ";\n";
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
SysNameAlphaSysNameBeta = 01;
Run Code Online (Sandbox Code Playgroud)
但我想要这样的输出:
SysNameAlpha = 0;
SysNameBeta = 1;
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我有以下xml
<?xml version="1.0" encoding="utf-8"?>
<Response>
<Function Name="GetSomethingById">
<something idSome="1" Code="1" Description="TEST01" LEFT="0" RIGHT="750" />
</Function>
</Response>
Run Code Online (Sandbox Code Playgroud)
我希望<something>节点的属性作为哈希.我试着像下面
my $xpc = XML::LibXML::XPathContext->new(
XML::LibXML->new()->parse_string($xml) # $xml is containing the above xml
);
my @nodes = $xpc->findnodes('/Response/Function/something');
Run Code Online (Sandbox Code Playgroud)
我希望有$nodes[0]->getAttributes任何帮助吗?
简单的removeChild测试,虽然删除了xml行,但它保持一个空的空行,怎么来的?顺便说一句 - 我的源xml文件确实有缩进,但即使我删除它们我得到相同的结果.那么,如果仍然保留一个空格,那么删除子行的意义何在?
有没有办法在将结果xml行输出到文件之前重新格式化?
foreach my $XYZ ($doc->findnodes("//EE1"))
{
my $library = $XYZ->parentNode;
$library->removeChild($XYZ);
}
print {$FH} $doc->toString(0);
RESULT IN OUTPUT FILE:
<?xml version="1.0"?>
<TopTag>
<AA1>ZNY</AA1>
<AA2>111</AA2>
<BB1>
<CC1>ZNY</CC1>
<CC2>
<DD1>
<-----blank line remains
<EE2>2000</EE2>
</DD1>
<DD1>
<-----blank line remains
<EE2>5000</EE2>
</DD1>
</CC2>
</BB1>
<AA1>ZNY2</AA1>
<AA2>2</AA2>
</TopTag>
Run Code Online (Sandbox Code Playgroud) 以下工作代码读取XML包含大量空元素的文件,然后应用2个更改并以不同的名称再次保存.但它也会改变空元素,比如<element></element>自我关闭的标签,如<element />不需要的.
如何保存它不使用自动关闭标签?或者用另一个词来告诉XML::LibXML如何使用空标签?原始文件是在商业应用程序中生成的,它使用带有空元素的样式,所以我想维持它.
#! /usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
my $filename = 'out.xml';
my $dom = XML::LibXML->load_xml(location => $filename);
my $query = '//scalar[contains(@name, "partitionsNo")]/value';
for my $i ($dom->findnodes($query)) {
$i->removeChildNodes();
$i->appendText('16');
}
open my $out, '>', 'out2.xml';
binmode $out;
$dom->toFH($out);
# now out2.xml has only self-closing tags where previously
# were used empty elements
Run Code Online (Sandbox Code Playgroud) 我想转储xml doc树,类似于转储perl数据类型的方式。
use Data::Dumper;
print Dumper($foo);
Run Code Online (Sandbox Code Playgroud)
递归地转储包含的结构$foo(即使存在循环依赖性)。
然而
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($filename);
my @nodes = $doc->findnodes($path);
foreach(@nodes)
{
print Dumper($_);
}
Run Code Online (Sandbox Code Playgroud)
只是打印像
$VAR1 = bless( do{\(my $o = 46232224)}, 'XML::LibXML::Element' );
Run Code Online (Sandbox Code Playgroud)
我想得到一棵LibXML树-代表XML结构的元素。
我在使用 XML::LibXML 时遇到一些问题,我想知道是否有办法做我想做的事情,或者是否应该更改我的 XML。
目前,我的 XML 如下所示:
<fftg>
<actions>
<rename>
<mandatory>0</mandatory>
<other_things_here />
</rename>
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<other_things_here />
</transfer>
<transfer>
<mandatory>1</mandatory>
<protocol>FTP</protocol>
<other_things_here />
</transfer>
<archive>
<mandatory>1</mandatory>
<other_things_here />
</archive>
<rename>
<mandatory>1</mandatory>
<other_things_here />
</rename>
</actions>
</fftg>
Run Code Online (Sandbox Code Playgroud)
如您所见,在“actions”下,可以有不同类型的操作(每种操作有 1 个或多个操作,每个操作下有不同的内容)
我想浏览每个操作并根据该操作执行特定的操作。
我的问题是:由于存在多个同类操作,因此脚本无法正常工作并覆盖前一个同类操作,或者特定操作上的循环会在同类每个操作上重新循环
示例1:
foreach my $transfer ($doc->findnodes('/fftg')) {
# Browse Actions
foreach my $action ($doc->findnodes('/fftg/actions/*')) {
my $action_name = $action->nodeName();
my $actiontype = ucfirst($action->nodeName());
print "executing action $action_name ..\n";
# Browse action details
foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) {
for …Run Code Online (Sandbox Code Playgroud)