我正在尝试使用 Perl 脚本或 xslt 在 XML 模式中将命名的复杂类型转换为匿名类型。
元素名称和类型可以是动态的。
XML 架构示例:
<xsd:element name="person" type="Person"/>
<xsd:element name="person2" type="Person"/>
<xsd:complexType name="Person">
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
将转换为:
<xsd:element name="person">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="person2">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
任何帮助将不胜感激!
它只是一个XML文件,所以使用你最喜欢的XML解析器。
use XML::LibXML qw( );
use XML::LibXML::XPathContext qw( );
sub resolve_qname {
my ($context_node, $qname) = @_;
my $local_part = $qname;
my $namespace = $local_part =~ s/^([^:]*)://
? $context_node->lookupNamespaceURI($1) // $1 : '';
return "{$namespace}$local_part";
}
my $in_qfn = '...';
my $out_qfn = '...';
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($in_qfn);
my $root = $doc->documentElement();
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(xs => 'http://www.w3.org/2001/XMLSchema');
my %unsupported;
my %type_nodes_by_name;
for my $type_node ($xpc->findnodes('xs:complexType', $root)) {
my $type_name = $type_node->getAttribute('name')
or next;
$type_node->removeAttribute('name');
$type_nodes_by_name{resolve_qname($type_node, $type_name)} = $type_node;
}
for my $element_node ($xpc->findnodes('//xs:element', $root)) {
my $type_name = $element_node->getAttribute('type')
or next;
my $type_node = $type_nodes_by_name{resolve_qname($element_node, $type_name)}
or next;
$element_node->removeAttribute('type');
$element_node->appendChild($type_node->cloneNode(1));
}
for my $type_node (values(%type_nodes_by_name)) {
$type_node->parentNode()->removeChild($type_node);
}
$doc->toFile($out_qfn);
输入:
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="person" type="Person"/>
<xsd:element name="person2" type="Person"/>
<xsd:complexType name="Person">
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
输出(美化后):
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="person">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="person2">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="first" type="xsd:string"/>
<xsd:element name="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
resolve_qname
并不准确,但可能足够好。