Xslt XSL-根据其他元素的可用性使元素成为必需元素

Xslt XSL-根据其他元素的可用性使元素成为必需元素,xslt,xslt-2.0,Xslt,Xslt 2.0,我正在使用XSL文件基于以下Xml创建XSD。实际上,我只想在每个节点(Sample、Sample1等)中都有Element1块可用时,才强制使用Element2块(minOccurs=1)。如果Element1块不可用,则Element2块应变为可选(minOccurs=0)。我尝试了祖先::[],匹配等,但没有任何效果。请帮忙 Xml 0 1. 2. 1. 2. XSL 听起来好像你只想让Element2拥有minOccurs=“1”当它有Element1兄弟时 XPath/*[matc

我正在使用XSL文件基于以下Xml创建XSD。实际上,我只想在每个节点(Sample、Sample1等)中都有Element1块可用时,才强制使用Element2块(minOccurs=1)。如果Element1块不可用,则Element2块应变为可选(minOccurs=0)。我尝试了祖先::[],匹配等,但没有任何效果。请帮忙

Xml

0
1.
2.
1.
2.
XSL
听起来好像你只想让
Element2
拥有
minOccurs=“1”
当它有
Element1
兄弟时

XPath
/*[matches(local-name(),'Element1')]
使用子体轴,因此它跳到XML树的顶部并查看整个文档以测试是否存在
Element1
元素

相反,您希望将其仅约束到
Element2
父项下的元素:
。/*[local-name()eq'Element1']
或者如果您只关心
Element2
父项的子项,则可以使用:
。/*[local-name()eq'Element1']

我认为您可以进一步简化和整合,并将条件逻辑移到minOccurs属性中,使用属性值模板计算
1
0
的值:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output indent="yes"/>
    
  <xsl:template match="*">
    <xs:element name="{local-name()}" 
      minOccurs="{if (local-name() = 'Element2' and ..//*[local-name() eq 'Element1']) then 1 else 0}">
      <xsl:call-template name="renderChildElements" />
    </xs:element>
  </xsl:template>
    
  <xsl:template name="renderChildElements">
    <xs:complexType>
      <xs:all minOccurs="0">
        <xsl:apply-templates select="*"/>
      </xs:all>
      <xsl:apply-templates select="@*"/>
    </xs:complexType>
  </xsl:template>
    
</xsl:stylesheet>

听起来好像你只想让
Element2
拥有
minOccurs=“1”
当它有
Element1
兄弟时

XPath
/*[matches(local-name(),'Element1')]
使用子体轴,因此它跳到XML树的顶部并查看整个文档以测试是否存在
Element1
元素

相反,您希望将其仅约束到
Element2
父项下的元素:
。/*[local-name()eq'Element1']
或者如果您只关心
Element2
父项的子项,则可以使用:
。/*[local-name()eq'Element1']

我认为您可以进一步简化和整合,并将条件逻辑移到minOccurs属性中,使用属性值模板计算
1
0
的值:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output indent="yes"/>
    
  <xsl:template match="*">
    <xs:element name="{local-name()}" 
      minOccurs="{if (local-name() = 'Element2' and ..//*[local-name() eq 'Element1']) then 1 else 0}">
      <xsl:call-template name="renderChildElements" />
    </xs:element>
  </xsl:template>
    
  <xsl:template name="renderChildElements">
    <xs:complexType>
      <xs:all minOccurs="0">
        <xsl:apply-templates select="*"/>
      </xs:all>
      <xsl:apply-templates select="@*"/>
    </xs:complexType>
  </xsl:template>
    
</xsl:stylesheet>


什么不起作用?您能否提供所需输出的示例?也许还有一个更完整的样式表?生成特定于一个XML实例的模式似乎是一件非常奇怪的事情。你想达到什么目标?当然有更好的工具可以做到这一点?什么不起作用?您能否提供所需输出的示例?也许还有一个更完整的样式表?生成特定于一个XML实例的模式似乎是一件非常奇怪的事情。你想达到什么目标?当然有更好的工具吗?
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output indent="yes"/>
    
  <xsl:template match="*">
    <xs:element name="{local-name()}" 
      minOccurs="{if (local-name() = 'Element2' and ..//*[local-name() eq 'Element1']) then 1 else 0}">
      <xsl:call-template name="renderChildElements" />
    </xs:element>
  </xsl:template>
    
  <xsl:template name="renderChildElements">
    <xs:complexType>
      <xs:all minOccurs="0">
        <xsl:apply-templates select="*"/>
      </xs:all>
      <xsl:apply-templates select="@*"/>
    </xs:complexType>
  </xsl:template>
    
</xsl:stylesheet>