Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl或xslt:将XML模式命名类型转换为匿名类型_Xml_Perl_Xslt_Xslt 1.0 - Fatal编程技术网

Perl或xslt:将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=

我正在尝试使用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不是,但可能已经足够好了。

我觉得这很合适,或者你是在问如何以编程方式转换它?是的,编写一个Perl或xslt脚本来自动转换它。谢谢@ikegami,你的脚本可以用于固定名称和类型,我非常确信,经过一些修改,它将与动态元素一起工作,并以递归方式工作!待核实!更新以处理所有复杂类型。