关于使用XSLT列出XML文件中的每个节点的another thread,Alejandro提供了this useful piece of XPath 2.0 code:
编辑:我的样式表现在使用Alejandro在评论中发布的代码的修改版本。它报告元素的@name属性。
我已经对其进行了大量修改,以应用于.xsd架构,如下所示:
示例模式(此source的简化版)
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="comment" type="xsd:string">
<xsd:annotation>
<xsd:documentation>doc for comment</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="USAddress">
<xsd:annotation>
<xsd:documentation>doc for USAddress</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:annotation>
<xsd:documentation>doc for SKU</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
我的XSLT样式表:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:template match="*|@*">
<xsl:value-of select="
string-join(
distinct-values(
(//*|//@*)
/string-join(
(ancestor::node()/name(),
if (self::attribute())
then concat('@',name())
else if (self::*[@name])
then concat(name(),'[@name="',@name,'"]')
else name()),
'/')),
'
')
"/>
</xsl:template>
</xsl:stylesheet>
结果:
/xsd:schema
/xsd:schema/xsd:annotation
/xsd:schema/xsd:annotation/xsd:documentation
/xsd:schema/xsd:annotation/xsd:documentation/@xml:lang
/xsd:schema/xsd:element[@name="comment"]
/xsd:schema/xsd:element/@name
/xsd:schema/xsd:element/@type
/xsd:schema/xsd:element/xsd:annotation
/xsd:schema/xsd:element/xsd:annotation/xsd:documentation
/xsd:schema/xsd:complexType[@name="USAddress"]
/xsd:schema/xsd:complexType/@name
/xsd:schema/xsd:complexType/xsd:annotation
/xsd:schema/xsd:complexType/xsd:annotation/xsd:documentation
/xsd:schema/xsd:complexType/xsd:sequence
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element[@name="name"]
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/@name
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/@type
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element[@name="street"]
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element[@name="city"]
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element[@name="state"]
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element[@name="zip"]
/xsd:schema/xsd:complexType/xsd:attribute[@name="country"]
/xsd:schema/xsd:complexType/xsd:attribute/@name
/xsd:schema/xsd:complexType/xsd:attribute/@type
/xsd:schema/xsd:complexType/xsd:attribute/@fixed
/xsd:schema/xsd:simpleType[@name="SKU"]
/xsd:schema/xsd:simpleType/@name
/xsd:schema/xsd:simpleType/xsd:annotation
/xsd:schema/xsd:simpleType/xsd:annotation/xsd:documentation
/xsd:schema/xsd:simpleType/xsd:restriction
/xsd:schema/xsd:simpleType/xsd:restriction/@base
/xsd:schema/xsd:simpleType/xsd:restriction/xsd:pattern
/xsd:schema/xsd:simpleType/xsd:restriction/xsd:pattern/@value
出于此问题的目的,此输出正常。
现在,而不是问“我的代码有什么问题?”我只想问一下从实际工作的基础状态开始的最佳方法。
我需要添加一个子句,对于/xsd:documentation
孙子的每一行,都附加<xsd:documentation>foo</xsd:documentation>
的文本。所以这一行:
/xsd:schema/xsd:element[@name="comment"]
变为:
/xsd:schema/xsd:element[@name="comment"] | doc for comment
谢谢, 马特
答案 0 :(得分:3)
解决方案很简单:
0.1。在样式表中定义xsd
命名空间:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
0.2。变化:
.//documentation
到
.//xsd:documentation
BTW,这是错误的:
//xsd|//@*
文档中没有名为xsd
的元素。可能你想要:
//xsd:*|//@*
此外,无需在属性上使用local-name()
,只需name()
即可。
第二次观察:
亚历杭德罗的解决方案没有任何问题。应用于提供的XML文档,它会生成以下正确的输出:
/xsd:schema
/xsd:schema/xsd:annotation
/xsd:schema/xsd:annotation/xsd:documentation
/xsd:schema/xsd:annotation/xsd:documentation/@xml:lang
/xsd:schema/xsd:element
/xsd:schema/xsd:element/@name
/xsd:schema/xsd:element/@type
/xsd:schema/xsd:element/xsd:annotation
/xsd:schema/xsd:element/xsd:annotation/xsd:documentation
/xsd:schema/xsd:complexType
/xsd:schema/xsd:complexType/@name
/xsd:schema/xsd:complexType/xsd:sequence
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/@name
/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/@type
/xsd:schema/xsd:complexType/xsd:attribute
/xsd:schema/xsd:complexType/xsd:attribute/@name
/xsd:schema/xsd:complexType/xsd:attribute/@type
/xsd:schema/xsd:complexType/xsd:attribute/@fixed
/xsd:schema/xsd:complexType/xsd:annotation
/xsd:schema/xsd:complexType/xsd:annotation/xsd:documentation
/xsd:schema/xsd:simpleType
/xsd:schema/xsd:simpleType/@name
/xsd:schema/xsd:simpleType/xsd:restriction
/xsd:schema/xsd:simpleType/xsd:restriction/@base
/xsd:schema/xsd:simpleType/xsd:restriction/xsd:pattern
/xsd:schema/xsd:simpleType/xsd:restriction/xsd:pattern/@value
/xsd:schema/xsd:simpleType/xsd:annotation
/xsd:schema/xsd:simpleType/xsd:annotation/xsd:documentation
答案 1 :(得分:0)
.//xsd:documentation
试图获取架构中的所有文档子项。我使用./xsd:documentation
来解决问题。
在测试后报告任何元素的文档以查看它是否属性的新子句:
concat(
if (self::*[@name])
then @name
else name()
, ./xsd:documentation)
感谢大家的帮助。