Удалите неиспользуемые элементы из схемы XML с помощью XSLT - PullRequest
12 голосов
/ 13 апреля 2011

Я ищу способ (если это вообще возможно) использовать 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 и не могу ничего найти по этому поводу - я не уверен, означает ли это, что это невозможно или нет.

Спасибо!

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

1 Ответ

4 голосов
/ 13 апреля 2011

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

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...