Retrieving / documenting child context nodes with XPath

In another thread about using XSLT to list each node in an XML file, Alejandro suggested this useful piece of XPath 2.0 code:

EDIT: my stylesheet below now uses a modified version of the code that Alejandro kindly posted in a comment. It reports the @name attribute of the elements.

I changed it a lot to apply to the .xsd schema as follows:

Circuit example

(simplified version of this 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>
My XSLT stylesheet:
<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=&quot;',@name,'&quot;]')
        else name()),
'/')),
'&#xA;')
"/>
    </xsl:template>
    </xsl:stylesheet>
Results:
/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

This result is suitable for the purpose of this question.

Now, instead of asking, "What happened to my explicit code?" I will just ask the best way to move from a basic state that really works.

, /xsd:documentation <xsd:documentation>foo</xsd:documentation>. , :

/xsd:schema/xsd:element[@name="comment"]

:

/xsd:schema/xsd:element[@name="comment"] | doc for comment

, Matt

+3
2

:

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

, :

//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
+3

.//xsd:documentation . , ./xsd:documentation .

, , , :

concat(
if (self::*[@name]) 
then @name
else name()
, ./xsd:documentation)

.

0

Source: https://habr.com/ru/post/1791057/


All Articles