В другом потоке об использовании XSLT для перечисления каждого узла в файле XML, Алехандро предложил этот полезный фрагмент кода XPath 2.0:
РЕДАКТИРОВАТЬ: моя таблица стилейниже теперь используется модифицированная версия кода, которую Алехандро любезно разместил в комментарии.Он сообщает атрибут @name элементов.
Я сильно изменил его, чтобы применить к схеме .xsd, например:
Пример схемы
(упрощенная версия этого источника )
<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
Спасибо, Мэтт