2010-05-11 3 views
3

Другой XSD вопрос - как я могу добиться того, что следующие элементы XML являются действительными:Различные суб-элементы, в зависимости от значения атрибута/элемента

<some-element> 
    <type>1</type> 
    <a>...</a> 
</some-element> 

<some-element> 
    <type>2</type> 
    <b>...</b> 
</some-element> 

суб-элементы (либо<a>или<b>) должно зависеть от содержимого <type> (также может быть атрибутом). Было бы так просто в RelaxNG - но RelaxNG не поддерживает ключа целостности :(

Есть ли способ осуществить это в XSD

Примечание: XML-схема версии 1.1 поддерживает <xs:alternative>, что может быть решение? , но AFAIK не ссылочной реализации (например libxml2) поддерживает это еще Так что я ищу обходные единственный способ я придумал это:...

<type>1</type> 
<some-element type="1"> 
    <!-- simple <xs:choice> between <a> and <b> goes here --> 
    <a>...</a> 
</some-element> 
<!-- and now create a keyref between <type> and @type --> 

ответ

2

нет, XML Schema 1.0 не может сделать это

3

Лучшим решением является удаление <type/> и только xs:choice для <a/> и <b/> и пусть приложение, использующее XML, сортирует тип.

Другим решением может быть иметь xs:choice для <a/> и <b/> использовать сценарий XSLT, чтобы сделать валидацию <type/> элемента по отношению к <a/> и <b/>.

Сначала проверьте xml на xmlschema, а затем используйте xslt для преобразования на нем, если результат преобразования пустой строки, он действителен, иначе будет отображаться итоговая строка в виде сообщения об ошибке.

Что-то вроде этого ...

XmlSchema:

<xs:element name="some-element"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="type" type="xs:integer" /> 
     <xs:choice> 
      <xs:element name="a" type="xs:string" /> 
      <xs:element name="b" type="xs:string" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:demo="uri:demo:namespace"> 
    <xsl:output method="text" /> 
    <xsl:template match="/demo:some-element"> 
    <xsl:if test="type = 1 and not(demo:a)"> 
     When type equals 1 element a is requred. 
    </xsl:if> 
    <xsl:if test="type = 2 and not(demo:b)"> 
     When type equals 2 element b is requred. 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
Смежные вопросы