Подтвердить что ты не робот

Удаление неиспользуемых элементов из схемы XML с помощью XSLT

Я ищу способ (если это возможно) использования XSL-преобразования документа XSD для удаления неиспользуемых элементов. Это очень много работает в моей работе, где компания будет определять XSD с абсолютно всем в ней, но тогда они захотят создать сокращенную версию для одного корневого элемента внутри него.

Чтобы объяснить далее, у меня может быть XSD, как показано ниже:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="RootElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ChildElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="ChildElement"/>
    <xs:element name="UnusedElement"/>
</xs:schema>

То, что я хотел бы сделать, это настроить XSL, где я предоставляю начальный элемент (в данном случае RootElement), и он будет копировать все зависимые элементы, но опустить неиспользуемые. В приведенном выше примере, если я прошел в RootElement, я ожидал увидеть RootElement и ChildElement, но UnusedElement опущен.

(Когда я говорю "предоставить начальный элемент", я очень рад взломать таблицу стилей и наберите xsl:template match="RootElement" там, где это требуется.)

Это, очевидно, должно быть рекурсивным, поэтому будет перемещаться по всей структуре, определенной ниже стартового элемента, и любой элемент в этой схеме, которая не была использована, будет отброшена.

(Конечно, было бы даже лучше, если бы он мог сделать то же самое в любых импортированных схемах!)

Я много раз искал Google и не могу найти что-либо на этом - я не уверен, что это означает, что это невозможно или нет.

Спасибо!

Изменить. На самом деле я, вероятно, должен уточнить и сказать, что я хотел бы удалить неиспользуемые элементы AND, поэтому он будет следовать за ссылками ref="childElement" и type="someType".

4b9b3361

Ответ 1

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="ptopElementName" select="'RootElement'"/>

 <xsl:variable name="vTop" select=
 "/*/xs:element[@name=$ptopElementName]"/>

 <xsl:variable name="vNames"
      select="$vTop/descendant-or-self::*/@name"/>

 <xsl:variable name="vRefs"
      select="$vTop/descendant-or-self::*/@ref"/>

 <xsl:variable name="vTypes"
      select="$vTop/descendant-or-self::*/@type"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="xs:element">
  <xsl:if test=
    "@name=$vNames
    or
     @name=$vRefs
    or
     ancestor-or-self::*[@name=$ptopElementName]">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>

 <xsl:template match="xs:complexType|xs:simpleType">
  <xsl:if test=
   "@name=$vTypes
    or
     ancestor-or-self::*[@name=$ptopElementName]">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="RootElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ChildElement"/>
            </xs:sequence>
        </xs:complexType></xs:element>
    <xs:element name="ChildElement"/>
    <xs:element name="UnusedElement"/>
</xs:schema>

создает желаемый результат:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="RootElement">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="ChildElement"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="ChildElement"/>
</xs:schema>