XSI 命名空间复制到结果序列
XSI Namespace Copied To Result Sequence
我有一个 XML 文件,其中包含一堆 look-ups。下面是一个简化版本:
<?xml version="1.0" encoding="UTF-8"?>
<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">
<Party name="Bens Birthday">
<ZIP>AB1234</ZIP>
<EMAIL>foo@bar.com</EMAIL>
<ATTENDEES>
<ATTENDEE>Bob</ATTENDEE>
<ATTENDEE>David</ATTENDEE>
</ATTENDEES>
</Party>
</Parties>
我写了一个简单的 XSD 来验证这个数据:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Parties">
<xs:complexType>
<xs:sequence>
<xs:element name="Party" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ZIP" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="EMAIL" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="ATTENDEES" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="ATTENDEE" minOccurs="1" maxOccurs="unbounded" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
这个效果很好。
我正在将 XML 文件加载到 XSLT 中并将其用作转换中的 look-up。
<xsl:variable name="party-details" select="document($party-file)/Parties"/>
<xsl:variable name="party-map" select="$party-details/Party[@name='Bens Birthday']"/>
这在我询问文本节点时效果很好:
<FOO>{$party-map/EMAIL}</FOO>
但是如果我尝试对序列执行相同的操作:
<xsl:sequence select="$party-map/ATTENDEES/ATTENDEE"/>
我从党XML继承命名空间定义文件:
<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">
导致这样的输出:
<ATTENDEE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Bob</ATTENDEE>
显然,如果我从 Party XML 文件中删除 xmlns:xsi
和 xsi:noNamespaceSchemaLocation
,问题就会消失...但是我没有验证它。
最终这会破坏我的 XSLT 输出验证,因为 ATTENDEE
元素上不允许使用 xsi
定义。
我有点明白这里发生了什么——Parties
的所有 children 都继承了名称空间 xmlns:xsi,所以当我将 ATTENDEE
序列拼接到我的 XSLT 输出时, XSLT 中缺少 xsi
定义意味着处理器会添加它。它不会为文本节点执行此操作,我假设,因为它们没有命名空间的概念,只有元素带有这个。
我可以通过在输出元素的其他位置定义 xmlns:xsi 和 XSLT 中 ATTENDEE
的 parent 来解决问题。
这仍然限制了我的输出格式。感觉我应该能够剥离命名空间,但我不知道如何继续。
有什么想法吗?或者,如果有人可以断然地说这是不可能的,还有其他建议吗?比如改用 DTD,或者完全不使用 XML 模式,并在 XSLT 内部进行验证?我现在猜!
不要使用 xsl:sequence
然后使用 xsl:copy-of copy-namespaces="no"
例如
<xsl:copy-of select="Parties/Party[@name = 'Bens Birthday']/ATTENDEES" copy-namespaces="no"/>
https://xsltfiddle.liberty-development.net/bdxtpU 使用您的样本作为主要输入,当然您也可以对 <xsl:copy-of select="$party-map/ATTENDEES/ATTENDEE" copy-namespaces="no"/>
.
做同样的事情
我有一个 XML 文件,其中包含一堆 look-ups。下面是一个简化版本:
<?xml version="1.0" encoding="UTF-8"?>
<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">
<Party name="Bens Birthday">
<ZIP>AB1234</ZIP>
<EMAIL>foo@bar.com</EMAIL>
<ATTENDEES>
<ATTENDEE>Bob</ATTENDEE>
<ATTENDEE>David</ATTENDEE>
</ATTENDEES>
</Party>
</Parties>
我写了一个简单的 XSD 来验证这个数据:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Parties">
<xs:complexType>
<xs:sequence>
<xs:element name="Party" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ZIP" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="EMAIL" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="ATTENDEES" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="ATTENDEE" minOccurs="1" maxOccurs="unbounded" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
这个效果很好。
我正在将 XML 文件加载到 XSLT 中并将其用作转换中的 look-up。
<xsl:variable name="party-details" select="document($party-file)/Parties"/>
<xsl:variable name="party-map" select="$party-details/Party[@name='Bens Birthday']"/>
这在我询问文本节点时效果很好:
<FOO>{$party-map/EMAIL}</FOO>
但是如果我尝试对序列执行相同的操作:
<xsl:sequence select="$party-map/ATTENDEES/ATTENDEE"/>
我从党XML继承命名空间定义文件:
<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">
导致这样的输出:
<ATTENDEE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Bob</ATTENDEE>
显然,如果我从 Party XML 文件中删除 xmlns:xsi
和 xsi:noNamespaceSchemaLocation
,问题就会消失...但是我没有验证它。
最终这会破坏我的 XSLT 输出验证,因为 ATTENDEE
元素上不允许使用 xsi
定义。
我有点明白这里发生了什么——Parties
的所有 children 都继承了名称空间 xmlns:xsi,所以当我将 ATTENDEE
序列拼接到我的 XSLT 输出时, XSLT 中缺少 xsi
定义意味着处理器会添加它。它不会为文本节点执行此操作,我假设,因为它们没有命名空间的概念,只有元素带有这个。
我可以通过在输出元素的其他位置定义 xmlns:xsi 和 XSLT 中 ATTENDEE
的 parent 来解决问题。
这仍然限制了我的输出格式。感觉我应该能够剥离命名空间,但我不知道如何继续。
有什么想法吗?或者,如果有人可以断然地说这是不可能的,还有其他建议吗?比如改用 DTD,或者完全不使用 XML 模式,并在 XSLT 内部进行验证?我现在猜!
不要使用 xsl:sequence
然后使用 xsl:copy-of copy-namespaces="no"
例如
<xsl:copy-of select="Parties/Party[@name = 'Bens Birthday']/ATTENDEES" copy-namespaces="no"/>
https://xsltfiddle.liberty-development.net/bdxtpU 使用您的样本作为主要输入,当然您也可以对 <xsl:copy-of select="$party-map/ATTENDEES/ATTENDEE" copy-namespaces="no"/>
.