2014-02-10 90 views
1

問題參考在XML文件中配置屬性:有沒有一種方法(使用類似tns:)建立一個XML文件.xsd配置來引用在XML文件配置屬性的列表在運行時?XSD配置在運行時

這是我的情況:

我有一個.xsd模式文件,Labels.xsd爲XML文件Labels.xml

Labels.xsd包含以下內容:

<complexType name="LabelList"> 
    <sequence> 
     <element name="label" type="tns:MyLabel" maxOccurs="unbounded" 
      minOccurs="1"/> 
    </sequence> 
</complexType> 

<complexType name="MyLabel"> 
    <attribute name="labelName" type="token" use="required"/> 
    <!-- There are other attributes and sequences in MyLabel --> 
</complexType> 

用戶可以添加到Labels.xml文件,並添加自己的自定義標籤,並更改名稱,而我的Java應用程序運行。這些更改在運行時收集。

我有另一個文件,MyMainTable.xml使用Tables.xsd架構。該文件使用上述Labels.xml文件中的標籤創建一個表格。該架構與Labels.xml文件的架構位於不同的架構文件中。

Tables.xml文件包含以下內容:Labels.xml

<complexType name="MyMainTable"> 
    <sequence> 
     <element name="table" maxOccurs="unbounded"> 
      <complexType> 
       <sequence> 
        <element name="tableElement" maxOccurs="unbounded"> 
         <complexType> 
          <attribute name="name" type="string" use="required"> 
           <annotation> 
            <documentation> 
            This should be one of the types of 
            MyLabel.label.labelName that are configured in the 
            LabelList sequence 
            Users can change the names of and add to the 
            types in MyLabel.labelName xml file. 
            </documentation> 
           </annotation> 
          </attribute> 
         </complexType> 
        </element> 
       </sequence> 
       <!-- There are other attributes in this type, but they are not relevant --> 
      </complexType> 
     </element> 
    </sequence> 
</complexType> 

例子:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Labels xmlns="<my schema locaiton>"> 

<FavoriteLabels> 
    <label labelName="LabelA"> 
    <!-- other attributes such as color --> 
    </label> 
    <label labelName="LabelB"> 
    <!-- other attributes such as color --> 
    </label> 
    <label labelName="LabelC"> 
    <!-- other attributes such as color --> 
    </label> 
</FavoriteLabels> 

<OtherLabels> 
    <label labelName="OtherA"> 
    <!-- other attributes such as color --> 
    </label> 
    <label labelName="OtherB"> 
    <!-- other attributes such as color --> 
    </label> 
    <label labelName="OtherC"> 
    <!-- other attributes such as color --> 
    </label> 
</OtherLabels> 
</Labels> 

在tableElement名稱可以是在FavoriteLabels列表或OtherLabels列表

目前在構建表時,我在Java代碼中執行檢查,但是我希望在解析XML文件時完成檢查。與.xsd文件中配置的Enum的檢查方式類似。

有沒有在.xsd配置的方式,以確保tableElementname屬性包含在用戶已經在Labels.xml配置文件在運行時的標籤列表?

+0

您可以顯示一個Labels.xml文件的簡短示例嗎? – helderdarocha

+0

@helderdarocha我添加了一個例子。這一切都不是從我的代碼中完全剪切和粘貼的,因爲還有其他的細節使得代碼更加複雜一些,與問題無關,但是xml文件基本上是從我的xml文件中複製並粘貼的,只是名稱改變和一些項目註釋掉。 – mdewitt

+0

這似乎是一個可以通過key/keyref解決的問題。你嘗試過使用它嗎?我有一個例子,我可以嘗試適應你的問題。 – helderdarocha

回答

1

我改編了下面的例子。它可能捕捉到您正在嘗試解決的問題,或者至少向您展示可能的策略。

這是一個包含標籤和表格的XML文件。

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://my-namespace my-schema.xsd" 
     xmlns="http://my-namespace"> 
    <labels> 
     <label label="LabelA"/> 
     <label label="LabelB"/> 
     <label label="LabelC"/> 
    </labels> 
    <tables> 
     <table name="LabelB"/> 
     <table name="LabelB"/> 
     <table name="LabelA"/> 
     <table name="LabelC"/> 
    </tables> 
</root> 

你或許可以使用單獨的文件(我是不能夠只使用XML模式,因爲鍵/ keyref關聯使用XPath做的,但它是可能的,或者你可以在內存中之前合併文件處理它們)。

在架構中,我定義了一個將標籤關聯到表的鍵/ keyref對。這些關聯是在XPath定義的元素的上下文中進行的。我使用ID和IDREF作爲標記類型,因爲它們更嚴格並保證整個文檔的唯一性。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" 
    xmlns:tns="http://my-namespace" targetNamespace="http://my-namespace"> 

    <xs:complexType name="LabelList"> 
     <xs:sequence> 
      <xs:element name="label" maxOccurs="unbounded" minOccurs="1"> 
       <xs:complexType> 
        <xs:attribute name="label" type="xs:ID" use="required"/> 
       </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="TableList"> 
     <xs:sequence> 
      <xs:element name="table" maxOccurs="unbounded"> 
       <xs:complexType> 
        <xs:attribute name="name" type="xs:IDREF" use="required"/>     
       </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:element name="root"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="labels" type="tns:LabelList"/> 
       <xs:element name="tables" type="tns:TableList"/> 
      </xs:sequence> 
     </xs:complexType> 

     <!-- These are the keys and references; they are in the current element's context --> 
     <xs:key name="LabelsKey"> 
      <xs:selector xpath="labels/label"/> 
      <xs:field xpath="@label"/> 
     </xs:key> 
     <xs:keyref name="TablesRef" refer="tns:LabelsKey"> 
      <xs:selector xpath="tables/table"/> 
      <xs:field xpath="@name"/> 
     </xs:keyref> 

    </xs:element> 
</xs:schema> 

現在,如果你添加未在列表中定義的標籤,如表:

<table name="LabelZ"/> 

你會得到一個驗證錯誤。

+0

你可以閱讀更多關於鍵/ keyref這裏:http://www.w3.org/TR/xmlschema-1/#declare-key – helderdarocha

+0

+1因爲這絕對是一個類似的情況一個很好的策略。不幸的是,因爲我們的模式被設置(模板在不同的xsd文件中),這是行不通的。但這聽起來像我們的架構設置的方式,沒有辦法在xml文件中進行驗證。它可能只是Java驗證。如果這是真的,我會接受這個答案,因爲你提到不得不合並文件。 – mdewitt