xml - 如何从 Perl 中的示例 XML 文档创建模式?

标签 xml perl xsd

我需要创建一个基于 XML 文件的 XSD 架构。是否有任何 Perl 模块可以执行此操作?

最佳答案

您可以使用任何 XSLT 处理器通过 XSL 转换创建 XSD。参见 XML::XSLT

XSD 文件包含两种元素类型:简单元素和复杂元素。所有叶节点都必须转换为简单类型元素,其他必须转换为复杂类型。叶节点是没有任何后代的节点。对应的 XPath 是 //*[not(descendant::element())]。下面的 XSLT 实现了这个方法:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
               elementFormDefault="qualified" 
               attributeFormDefault="unqualified">
      <xsl:for-each select="//*[not(descendant::element())]">
        <xsl:element name="xs:element">
          <xsl:attribute name="name">
            <xsl:value-of select="name()"/>
          </xsl:attribute>
          <xs:simpleType>
            <xs:restriction base="xs:string"/>
          </xs:simpleType>
        </xsl:element>
      </xsl:for-each>
      <xsl:for-each select="//*[descendant::element()]">
        <xsl:element name="xs:element">
          <xsl:attribute name="name">
            <xsl:value-of select="name()"/>
          </xsl:attribute>
          <xs:complexType>
            <xs:sequence>
              <xsl:for-each select="child::*">
                <xsl:element name="xs:element">
                  <xsl:attribute name="ref">
                    <xsl:value-of select="name()"/>
                  </xsl:attribute>
                </xsl:element>
              </xsl:for-each>
            </xs:sequence>
          </xs:complexType>
        </xsl:element>
      </xsl:for-each>
    </xs:schema>
  </xsl:template>
</xsl:stylesheet>

下面的例子:

<?xml version="1.0" encoding="UTF-8"?>
<person>
  <firstname>Peter</firstname>
  <lastname>Pan</lastname>
  <born>
    <year>1904</year>
    <month>12</month>
    <day>27</day>
  </born>
</person>

将产生以下架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">
  <xs:element name="firstname">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="lastname">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="year">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="month">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="day">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="firstname"/>
        <xs:element ref="lastname"/>
        <xs:element ref="born"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="born">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="year"/>
        <xs:element ref="month"/>
        <xs:element ref="day"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

关于xml - 如何从 Perl 中的示例 XML 文档创建模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5716620/

相关文章:

c# - .NET,为什么我必须使用 *Specified 属性来强制序列化?有没有办法不这样做?

基于 C 的 XML 解析器

javascript - zXml使用问题

perl - `fast_abs_path` "dangerous, but potentially faster"是什么方式?

perl - perl 中的 if 条件是否需要大括号?

python - svn 提交之前进行 XML 模式验证

xml - 尽管 minOccurs=0,但仍需要 XSD 元素

java - Android相对布局问题

xml - 在哪里可以浏览常见架构?

perl - 使用 perl 从行中提取元素的更好方法?