xml - 如何生成没有尾部 "/"的XML标签?

标签 xml perl

我正在尝试制作一个 XML 文档。尤其, 如下

<spirit:component xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4"
                xmlns:vendorExtensions="$IREG_GEN/XMLSchema/SPIRIT"     
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
                xsi:schemaLocation="$IREG_GEN/XMLSchema/SPIRIT/VendorExtensions.xsd 
                                    http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 
                                    http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd">

所以我为此制作了一个 perl 脚本,如下所示

use strict;
use warnings;

use Spreadsheet::ParseXLSX;
use XML::LibXML;
my $doc = XML::LibXML::Document->new('1.0', 'utf-8');
my $root = $doc->createElement('spirit:component');
#$root->appendChild($doc->createComment("JJ"));
$root->setAttribute('xmlns:spirit'=> "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4");
$root->setAttribute('xmlns:vendorExtensions'=> "\$IREG_GEN/XMLSchema/SPIRIT");
$root->setAttribute('xmlns:xsi'=> "http://www.w3.org/2001/XMLSchema-instance");
$root->setAttribute('xsi:schemaLocation'=> "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 
                                            http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 
                                            http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd");

$doc->setDocumentElement($root);
print $doc->toString(1);

但问题是我得到了结果

<spirit:component xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4" xmlns:vendorExtensions="$IREG_GEN/XMLSchema/SPIRIT" xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 &#10;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 &#10;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd"/>

特别是,这里有两个问题, index.xsd"/>

我可以删除换行符,然后按如下方式解决它

$root->setAttribute('xsi:schemaLocation'=> "http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 http://www.spiritconsortium.org/XMLSchema/SPIRIT/1
.4 http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd");

特别是,如何删除index.xsd"/>中的/?我使用了错误的函数吗?

最佳答案

在 XML 中,没有任何子项或其他封闭内容的标记可以且通常被编写为单个空元素形式 <foo/>而不是<foo></foo> 。但必须是其中之一;与 HTML 不同,在 XML 中,每个开始标记都需要一个结束标记。所以这部分输出没有任何问题。

对于xsi:schemaLocation的文本属性(需要有偶数个元素 - 它是命名空间和架构 URL 对)... &#9;是一个选项卡;用空格替换它们;这些不会被编码。不过,换行符仍然会。根据this answer关于属性文本中换行符是否有效的问题,entities are converted to characters and all whitespace in an attribute should be converted to spaces当使用 XML 解析器的程序请求内容时,由 XML 解析器解析。因此,虽然它看起来很丑陋,但在实践中使用符合规范的 XML 解析器,您所拥有的应该不会引起问题。

通过将脚本的输出传输到此进行测试:

#!/usr/bin/env perl                                                                                                                                                                                                                              
use warnings;                                                                                                                                                                                                                                    
use strict;                                                                                                                                                                                                                                      
use feature qw/say/;                                                                                                                                                                                                                             
use XML::LibXML;                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                 
my $dom = XML::LibXML->load_xml({ IO => \*STDIN });                                                                                                                                                                                              
my $root = $dom->documentElement();                                                                                                                                                                                                              
for my $attr ($root->attributes()) {
    say $attr->name(), " is ", $attr->getValue();
}

打印出来

schemaLocation is http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 
                                            http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4 
                                            http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4/index.xsd
xmlns:spirit is http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4
xmlns:vendorExtensions is $IREG_GEN/XMLSchema/SPIRIT
xmlns:xsi is http://www.w3.org/2001/XMLSchema-instance

至少对于 libxml2 来说似乎是这样。

关于xml - 如何生成没有尾部 "/"的XML标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72989729/

相关文章:

perl - 获取模块中明确定义的方法/函数列表

Perl:修剪字符串前导和尾随空格的函数

perl - 将 -1 分配给 $#array 有什么作用?

perl - 如何只读取文件的第一行

jQuery AJAX 到 Perl JSON 模块数据解码

xml - 如何在 Perl 中过滤/缩小 XML 以忽略不需要的子元素?

xml - 使用 XSLT 更改 SOAP namespace

xml - 使用 XSL 将 XML 中的日期时间元素拆分为日期和时间

java - 比较两个 xml 文件中的特定元素 -- 在 java 中

java - 如何解析文档中多次出现的 XML 元素的内容