6

私は、ユーザーが JSP ファイルに本質的に似ている XHTML 風のドキュメントを作成するのに役立つツールに取り組んでいます。ドキュメントは XML であり、XHTML 名前空間の適切な形式のタグを含めることができます。それらの間には、私の製品の名前空間の要素が織り込まれています。特に、このツールは XSD を使用して入力を検証します。

入力例:

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <c:paragraph>
        <span>This is a test!</span>
        <a href="http://www.google.com/">click here for more!</a>
      </c:paragraph>
    </c:section>
  </html>
</markup>

私の問題は、要素のネストの深さに応じて、XSD 検証が一貫して動作しないことです。私が望むのは、名前空間内のすべての要素がhttps://my_tag_lib.example.com/スキーマに対してチェックされ、名前空間内のすべての要素http://www.w3.org/1999/xhtmlが自由に許容されることです。私の XSD で許可されているすべての HTML 要素をリストするのではなく、特定のブラウザーなどでのみ使用できる不明瞭な要素をユーザーが使用したい場合があります。代わりに、名前空間に属する要素を<xs:any>.

私が発見したのは、状況によっては、my_tag_lib名前空間に属しているがスキーマに表示されていない要素は検証に合格しているのに対し、スキーマに表示されている他の要素は無効な属性を与えることで失敗させることができるということです。

* 有効な要素は XSD スキーマに対して検証されます * 無効な要素はバリデータによってスキップされますか?

たとえば、これは検証に合格します。

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <div>
        <c:my-invalid-element>This is a test</c:my-invalid-element>
      </div>
    </c:section>
  </html>
</markup>

しかし、これは検証に失敗します:

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <div>
        <c:paragraph my-invalid-attr="true">This is a test</c:paragraph>
      </div>
    </c:section>
  </html>
</markup>

認識されていない要素がまったくサニタイズされていないように見えるのに、認識された要素のスキーマに対して属性が検証されているのはなぜですか? ここでのロジックは何ですか?私はxmllint検証を行うために使用しています:

xmllint --schema markup.xsd example.xml

ここに私のXSDファイルがあります:

ファイル:markup.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <xs:import namespace="http://www.w3.org/1999/xhtml" schemaLocation="html.xsd" />
  <xs:element name="markup">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element ref="xhtml:html" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

ファイル:html.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3.org/1999/xhtml">
  <xs:import namespace="https://my_tag_lib.example.com/" schemaLocation="my_tag_lib.xsd" />
  <xs:element name="html">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

ファイル:my_tag_lib.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://my_tag_lib.example.com/">
  <xs:element name="section">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="paragraph">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>
4

2 に答える 2

2

あなたが見逃しているのは、コンテキストによって決定される宣言の理解です。

まず、この小さな実験を見てください。

<?xml version="1.0"?>
<markup>
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
        <c:section>
            <div>
                <html>
                    <c:my-invalid-element>This is a test</c:my-invalid-element>
                </html>
            </div>
        </c:section>
    </html>
</markup>

これは、c:my-invalid-element が「lax」から「strict」に評価されるコンテキストを変更したことを除いて、有効な例と同じです。これは、html 要素を差し挟むことによって行われます。これにより、タグの名前空間内のすべての要素が厳密になります。簡単に確認できるように、上記は無効です。

これは、(ドキュメントを読まなくても)あなたの例では、決定されたコンテキストが「厳密」である期待とは対照的に「緩い」ものでなければならないことを示しています。

文脈が緩いのはなぜ?divは「緩く」処理されます (ワイルドカードに一致しますが、その定義は存在しません)。そのため、その子は緩く評価されます。lax の意味との一致: 最初のケースでは、定義c:my-invalid-elementが見つかりませんでした。したがって、与えられた指示はdon't worry if you can't- すべて良いです。無効なサンプルでは、​​ の定義c:paragraphが見つかりました。したがってit must be ·valid· with respect to that definition、予期しない属性のため、良くありません。

于 2014-04-03T17:56:14.993 に答える
1

div要素は宣言されていないため、スキーマで無効な型を受け入れない場合に保持されるものは何もなく、要素paragraphは を許可しませんmy-invalid-attr

おそらく、いくつかの例がそれをより明確にするかもしれません。

要素が宣言され ( htmlsection、などparagraph)、そのコンテンツが taglib 名前空間 ( を持つと宣言した) からのものである場合、それらはstrictprocessContents="strict"として扱われます。つまり、属性または子要素を宣言する必要があります。これは検証に失敗するはずです:

<html>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</html>

これもそうです:

<c:section>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</c:section>

これ:

<div>
    <c:paragraph>
         <c:my-invalid-element>This is a test<c:my-invalid-element>
    </c:paragraph>
</div>

そしてこれ (属性はコンテンツの一部であるため):

<c:paragraph my-invalid-attr="true">This is a test</c:paragraph>

ただし、要素が宣言されていない場合( などdiv)、xs:any宣言と一致します。の内容を制限する宣言がないdivため、何でも許可されます。したがって、これは検証に合格する必要があります。

<div>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</div>

c:my-invalid-elementも宣言されていないため、任意のコンテンツまたは属性が許可されます。これは有効です:

<div>
    <c:my-invalid-element invalid-attribute="hi"> <!-- VALID -->
        <c:invalid></c:invalid>
        <html></html>
    </c:my-invalid-element>
</div>

ただし、無効な要素を 1 つの中htmlに配置すると、失敗します。

<div>
    <c:my-invalid-element invalid-attribute="hi">
        <html><c:invalid></c:invalid></html>  <!-- NOT VALID -->
    </c:my-invalid-element>
</div>

xs:anyネストの深さに関係なく、宣言された要素内で宣言されていない属性を使用すると( と一致しません)、同じことが起こります。

<div>
    <c:my-invalid-element invalid-attribute="hi"> <!-- VALID -->
        <c:invalid>
            <b> 
                <c:section bad-attribute="boo"></c:section> <!-- FAILS! -->
 ...
于 2014-04-01T17:44:41.733 に答える