如何在XSD中定义“文字”

时间:2011-12-08 19:48:43

标签: xsd

我是XSD的新手,而且非常智能。

我需要做的是以某种方式在XSD文件中定义'literal'元素,以便用户可以在XML文档中使用它。

例如: 在XML文档中,我想让用户能够添加如下元素:

  <WordBoundary/>

但是让XSD文件不仅定义名称'WordBoundary',还要定义中的元素列表,这些元素属于XSD中其他地方定义的类型。

这可能吗?

更新以提供更多信息:

我正在尝试编写一个XSD(或一组XSD),它提供了一个预定义元素库供最终用户使用。 这些元素最终将用于生成正则表达式,但我希望尽可能隐藏用户正则表达式的复杂性。 XSD将使用.NETs XSD.Exe生成C#类。

目前我已经定义了像和等等的元素,它们可以很好地工作,但依赖于它们在代码中定义的最终正则表达式模式。一些元素具有Pattern属性以允许微调,但​​这会使用户稍微混淆XML文档。 构建现有C#定义的示例:

const string BidMatch = @"(?<" + BidGroupName + ">" + DecimalNumberFragment + ")";
const string OfferMatch = @"(?<" + OfferGroupName + ">" + DecimalNumberFragment + ")";

const string BidOfferSpreadMatch = BidMatch + OptionalGap + RangeSeparatorFragment + OptionalGap + OfferMatch;

因此,我希望能够重构这一点,以便将所有正则表达式模式从代码移动到XSD定义中以形成库(或者如果事实证明不可能通过名称查找XML文件)诸如和常用的原语,但更复杂的结构,如等。

因此,使用可以直接在XML文档中使用预定义元素,但也可以像这样构建自己的元素:

<Group captureName="MyCustomMatch">
  <WordBoundary/>
        <Digit/>
        <Literal pattern="[xyz]" />
        <AnyOf/>
            <AnyOfChoice>
                <DecimalNumber />
                <Gap />
                <DecimalNumber />
            </AnyOfChoice>
            <AnyOfChoice>
                <LiteralText text="(" />
                <DecimalNumber />
                <LiteralText text=")" />
            </AnyOfChoice>
  <WordBoundary/>
</Group>

(事实上,库中预定义的元素将以相同的方式构建)

从代码的角度来看,我目前有AnyOf / Group等工作,通过查看元素类型并调用方法来生成模式。为了实现这一点,所有这些新元素都需要有一个共同的祖先,例如: RegexLiteral,我可以从中读取Pattern属性或其他内容,并将其添加到完整模式中。

我试过扩展一个普通类型并尝试覆盖其Pattern属性以使用固定属性,但XSD显然不允许这样做。

我希望这只是我XSD知识的限制,而不是XSD本身的限制,并希望你聪明的人知道实现这一目标的方法。

UPDATE2: 以为我有这个XSD片段

<xs:complexType name="LiteralFragment" abstract="true">
    <xs:attribute name="Pattern" type="xs:string" />
</xs:complexType>

<xs:complexType name="Fred">
    <xs:complexContent >
        <xs:extension base="LiteralFragment" >
            <xs:attribute name="Pattern" type="xs:string" fixed="BBB" />
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

但是XSD(以及Xsd2Code)产生了这个垃圾代码:

public partial class Fred : LiteralFragment
{

    private string pattern1Field;

    public Fred()
    {
        this.pattern1Field = "BBB";
    }

    [System.Xml.Serialization.XmlAttributeAttribute("Pattern")]
    public string Pattern1
    {
        get { return this.pattern1Field; }
        set { this.pattern1Field = value; }
    }
}

由于使用了两个带有“Pattern”的XmlAttributeAttribute而爆炸。 我需要的是一个XSD生成器,它足够聪明,可以实现这一点并生成这个代码:

public partial class Fred : LiteralFragment
{
    public Fred()
    {
        Pattern = "BBB";
    }
}

1 个答案:

答案 0 :(得分:0)

试试这个......

XSD:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="root" type="TRoot"/>

    <xsd:element name="WordBoundary">
        <xsd:complexType/>
    </xsd:element>

    <xsd:element name="SomethingElse">
        <xsd:complexType mixed="true">
            <xsd:sequence>
                <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="TRoot">
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

这个XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SomethingElse>Text <WordBoundary/> another <WordBoundary/>...</SomethingElse>
</root>

这是你的想法吗?