【问题标题】:XML XInclude looses namespace in included nodesXML XInclude 在包含的节点中丢失命名空间
【发布时间】:2015-03-12 15:42:03
【问题描述】:

我正在尝试在由更多文件组成的 xml 文件上使用命名空间。

XML 架构

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
    version="1.0"
    attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="urn:mynamespace"
    targetNamespace="urn:mynamespace">

    <xsd:element name="main_element" type="typeMainElement" />

    <xsd:complexType name="typeMainElement">
        <xsd:sequence>
            <xsd:element name="inner_element" type="typeInnerElement" />
        </xsd:sequence>
    <xsd:attribute name="test_attribute" type="xsd:string" use="required" />
    </xsd:complexType>

    <xsd:complexType name="typeInnerElement">
        <xsd:sequence>
            <xsd:element name="description" type="xsd:string" minOccurs="0" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

主要 XML

<main_element test_attribute="value"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns="urn:mynamespace">
    <inner_element>
        <description>Test</description>
    </inner_element>
</main_element>

XML Schema 验证 XML 效果很好。 但是,如果我尝试将 XML 的某些部分外包出去,依靠XInclude,那么就没有任何效果了。

拆分的 XML

<main_element test_attribute="value"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns="urn:mynamespace">
    <xi:include href="simple_part.xml" />
</main_element>

包含的 XML

<inner_element>
    <description>Test</description>
</inner_element>

尝试验证 Splitted XML 返回错误:

simple_part.xml:1:元素 inner_element:模式有效性错误:元素“inner_element”:不需要此元素。预期为 ( {urn:mynamespace}inner_element )。

simple_main_element.xml 验证失败

似乎当包括我失去了命名空间继承,所以被包含的内容不再有命名空间了。

-- 我如何解决这个问题,而不在任何地方添加命名空间前缀? --

-- 附加问题:如果包含来自另一个目录,例如&lt;xi:include href="subdir/simple_part.xml" /&gt;,如何解决问题?

【问题讨论】:

    标签: xml xml-namespaces xsd-validation xinclude


    【解决方案1】:

    好吧,看来您需要进行一些修改:

    1) 在您的 XML 片段中,您需要声明与“主”文档相同的命名空间

     <inner_element xmlns="urn:mynamespace">
       <description>Test</description>
     </inner_element>
    

    2) 在生成的文档中,xml:base 属性会自动设置为 (see XInclude spec, §4.5.5 and C.1),因此您必须通过声明此属性并导入 xml 命名空间来在架构中声明它,如下所示:

       <xsd:schema
           version="1.0"
           attributeFormDefault="unqualified"
           elementFormDefault="qualified"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xmlns="urn:mynamespace"
           targetNamespace="urn:mynamespace">
    
           <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd" />
    
           <xsd:element name="main_element" type="typeMainElement" />
    
           <xsd:complexType name="typeMainElement">
               <xsd:sequence>
                   <xsd:element name="inner_element" type="typeInnerElement" />
               </xsd:sequence>
           <xsd:attribute name="test_attribute" type="xsd:string" use="required" />
           </xsd:complexType>
    
           <xsd:complexType name="typeInnerElement">
               <xsd:sequence>
                   <xsd:element name="description" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
               <xsd:attribute ref="xml:base"/>
           </xsd:complexType>
       </xsd:schema>
    

    实体的替代解决方案

    您需要在“主”文档开头的 DOCTYPE 中声明(解析)实体,并使用引用而不是 &lt;xi:include&gt;,如下所示:

    <?xml version="1.0"?>
    <!DOCTYPE main_element [
      <!ENTITY simple_part SYSTEM "simple_part.xml">
    ]>
    <main_element test_attribute="value"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns="urn:mynamespace">
       <!-- call a reference instead of xi:include -->
       &simple_part_1;
    </main_element>
    

    simple_part.xml 将完全符合您在原始帖子中的要求:

    <inner_element>
      <description>Test</description>
    </inner_element>
    

    【讨论】:

    • @Kamafeather 如果此答案解决了您的问题,请接受。
    • 是的。我确实已经能够通过添加命名空间来解决它。解决方案没问题,但我想避免在架构中添加额外的xml:base 属性(在我看来,这与日期定义无关,而只是一种增加肮脏的解决方法[我不是在责怪你; 我知道这是常见的解决方案 ;) ])。无论如何,如果您想扩展答案,我添加了一个与包含 URI 相关的问题。
    • @Kamafeather 我突然想到:如果你不想修改你的架构,也许你可以使用一个好的旧实体引用?
    • 我没有明白实体引用可以为我做什么 -_-'
    • @Kamafeather 我已经在我的答案中添加了“实体”解决方案。
    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2014-03-16
    • 2016-12-18
    • 2011-01-02
    • 1970-01-01
    相关资源
    最近更新 更多