XML XInclude 在包含的节点中丢失命名空间
XML XInclude looses namespace in included nodes
我正在尝试在由更多文件组成的 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 架构 验证 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 returns 错误:
simple_part.xml:1: element inner_element: Schemas validity error : Element 'inner_element': This element is not expected. Expected is ( {urn:mynamespace}inner_element ).
simple_main_element.xml fails to validate
似乎在 including 时我失去了命名空间继承,因此包含的内容不再有命名空间。
-- 我该如何解决这个问题,而不是到处添加名称空间前缀? --
-- 添加的问题:在包含来自另一个目录的情况下如何解决问题,例如 <xi:include href="subdir/simple_part.xml" />
?
嗯,看来您需要进行一些修改:
1) 在您的 XML 片段中,您需要声明与 "master" 文档相同的名称空间
<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>
实体的替代解决方案
您需要在 "master" 文档开头的 DOCTYPE 中声明(已解析)实体,并使用引用而不是 <xi:include>
,如下所示:
<?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 将正是您在原始 post 中所需要的:
<inner_element>
<description>Test</description>
</inner_element>
我正在尝试在由更多文件组成的 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 架构 验证 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 returns 错误:
simple_part.xml:1: element inner_element: Schemas validity error : Element 'inner_element': This element is not expected. Expected is ( {urn:mynamespace}inner_element ).
simple_main_element.xml fails to validate
似乎在 including 时我失去了命名空间继承,因此包含的内容不再有命名空间。
-- 我该如何解决这个问题,而不是到处添加名称空间前缀? --
-- 添加的问题:在包含来自另一个目录的情况下如何解决问题,例如 <xi:include href="subdir/simple_part.xml" />
?
嗯,看来您需要进行一些修改:
1) 在您的 XML 片段中,您需要声明与 "master" 文档相同的名称空间
<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>
实体的替代解决方案
您需要在 "master" 文档开头的 DOCTYPE 中声明(已解析)实体,并使用引用而不是 <xi:include>
,如下所示:
<?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 将正是您在原始 post 中所需要的:
<inner_element>
<description>Test</description>
</inner_element>