Perl或xslt:将XML模式命名类型转换为匿名类型
我正在尝试使用Perl脚本或xslt将XML模式中的命名复杂类型转换为匿名类型 元素名称和类型可以是任何动态的 XML架构示例:Perl或xslt:将XML模式命名类型转换为匿名类型,xml,perl,xslt,xslt-1.0,Xml,Perl,Xslt,Xslt 1.0,我正在尝试使用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=
<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不是,但可能已经足够好了。我觉得这很合适,或者你是在问如何以编程方式转换它?是的,编写一个Perl或xslt脚本来自动转换它。谢谢@ikegami,你的脚本可以用于固定名称和类型,我非常确信,经过一些修改,它将与动态元素一起工作,并以递归方式工作!待核实!更新以处理所有复杂类型。