【问题标题】:Remove references from schema xsd从架构 xsd 中删除引用
【发布时间】:2014-10-07 19:04:00
【问题描述】:

有谁知道,如何转换 xsd 字符串包含对没有 'ref' 属性的字符串的引用?

例如我有架构:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pref="http://someaddr.com" elementFormDefault="qualified" targetNamespace="http://otheraddr.com">
   <xs:element name="rootElem">
     <xs:complexType>
       <xs:sequence>
         <xs:element ref="pref:elem1"/>
         <xs:element ref="pref:elem2"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
   <xs:element name="elem1" type="xs:string"/>
   <xs:element name="elem2" type="xs:string"/>
</xs:schema>

我想将其转换为:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pref="http://someaddr.com" elementFormDefault="qualified" targetNamespace="http://otheraddr.com">
   <xs:element name="rootElem">
     <xs:complexType>
       <xs:sequence>
         <xs:element name="elem1" type="xs:string"/>
         <xs:element name="elem2" type="xs:string"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
</xs:schema>

我正在寻找一些功能,例如 xerces 库,但我找不到任何东西。我自己用 Java 编写也有很多困难。

【问题讨论】:

  • 是否要将所有对全局元素的引用更改为局部元素声明?或者只有那些全局元素是xsd:string 类型的? (无论如何,我认为一个简单的 XSLT 样式表将是最简单的方法。)
  • 我想去掉全局文档中的所有 'ref' 属性,并替换包含 'ref' 属性的节点,适当的节点,这些都是用这个参考解决的

标签: java xml xsd schema


【解决方案1】:

描述这种转换的 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"
    >

  <!-- transform all attributes and nodes as themselves,
       except where a more selective rule applies -->
  <xsl:template match="@*|node()" mode="#all">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <!-- transform xs:element elements with ref attributes
       as a copy of the referenced schema-level xs:element -->
  <xsl:template match="xs:element[@ref]">
    <xsl:variable name="ref-name" select="@ref" as="xs:string" />
    <!-- the mode specified below doesn't matter; it just
         mustn't be the default mode -->
    <xsl:apply-templates
        select="/xs:schema/xs:element[@name=$ref-name]"
        mode="inline" />
  </xsl:template>

  <!-- in the default mode, transform schema-level
       xs:element elements to nothing -->    
  <xsl:template match="/xs::schema/xs:element[@name]" />

</xsl:stylesheet>

请注意,无论实现如何,请求的操作都可能需要无限递归。

【讨论】:

  • 这里有几个错误:它摆脱了所有的全局元素声明,这不是本意;并且它不对 QName 进行命名空间敏感匹配。后一个问题可以在 XSLT 2.0 中解决:将谓词更改为[QName(/*/@targetNamespace, @name) = resolve-QName(current()/@ref, current()]
  • 是的,“可能看起来像这样”的意思是我提供了一个起点,而不是一个完整的答案。确实,并非所有全局元素都应该被删除,但不清楚是什么标准决定了哪些应该保留。
  • 谢谢。 Xslt 可能是一个很好的解决方案,但我不知道我对 xsd 的了解是否足以让我自己编写这篇文章。我认为有一些内置方法可以处理我的 xsd 以摆脱所有引用并用适当的节点替换它们。问候
猜你喜欢
  • 1970-01-01
  • 2012-03-06
  • 2015-08-08
  • 1970-01-01
  • 2011-06-18
  • 2011-06-03
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多