如何使用XPath访问XML Schema中xs:appinfo元素内的信息
如何用XPath访问XML Schema中xs:appinfo内的嵌套XML元素
可以直接通过XPath访问xs:appinfo内的XML元素,这些内容不会被解析为纯文本。你的问题出在命名空间处理和XPath路径的细节上,以下是具体分析和修正方案:
示例XML Schema
<xs:schema targetNamespace="ts" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="MyElement"> <xs:complexType> <xs:sequence> <xs:element name="MyChildElement1" type="xs:string"/> <xs:element name="MyChildElement2" type="xs:string"> <xs:annotation> <xs:appinfo> <AppInfoElement1>Hello</AppInfoElement1> <AppInfoElement2>Hello</AppInfoElement2> </xs:appinfo> <xs:documentation xml:lang="en">Any documentation</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
问题分析
你尝试的XPath和XSLT代码无效,主要原因有两点:
AppInfoElement2属于空命名空间,但你的XSLT仅声明了xs命名空间,未对空命名空间做处理,导致XPath无法匹配到该元素。- 模板匹配的
//*[@name='MyChildElement2']写法不够精准,容易匹配到其他命名空间下的同名元素;同时模板内的相对路径未正确处理空命名空间元素。
修正方案
方案一:绑定空命名空间前缀
给空命名空间绑定一个前缀(比如app),直接通过前缀定位目标元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:app=""> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="xs:element[@name='MyChildElement2']" > <xsl:copy-of select="xs:annotation/xs:appinfo/app:AppInfoElement2/text()" /> </xsl:template> </xsl:stylesheet>
方案二:使用local-name()跳过命名空间检查
如果不想绑定额外前缀,可通过local-name()函数匹配元素的本地名称:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="xs:element[@name='MyChildElement2']" > <xsl:copy-of select="xs:annotation/xs:appinfo/*[local-name()='AppInfoElement2']/text()" /> </xsl:template> </xsl:stylesheet>
额外提示
- 模板匹配尽量精准,用
xs:element[@name='MyChildElement2']代替//*[@name='MyChildElement2'],避免误匹配其他命名空间的元素。 - xs:appinfo内的自定义XML元素默认属于空命名空间,必须通过上述两种方式之一处理,才能被XPath正确识别。
内容的提问来源于stack exchange,提问作者Thomas Schwere
相关产品推荐
相关产品推荐

