xml - Get /documentation children of context nodes with XPath -
on another thread using xslt list every node in xml file, alejandro offered this useful piece of xpath 2.0 code:
edit: stylesheet below uses modified version of code alejandro kindly posted in comment. reports @name attribute of elements.
i have heavily modified apply .xsd schema following:
example schema(a simplified version of source)
<xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema"> <xsd:annotation> <xsd:documentation xml:lang="en"> purchase order schema example.com. copyright 2000 example.com. rights reserved. </xsd:documentation> </xsd:annotation> <xsd:element name="comment" type="xsd:string"> <xsd:annotation> <xsd:documentation>doc comment</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:complextype name="usaddress"> <xsd:annotation> <xsd:documentation>doc 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, code identifying products --> <xsd:simpletype name="sku"> <xsd:annotation> <xsd:documentation>doc 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 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()) concat('@',name()) else if (self::*[@name]) concat(name(),'[@name="',@name,'"]') else name()), '/')), '
') "/> </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 output fine, purposes of question.
now, rather asking "what's wrong fugly code?" i'll ask best way proceed base state works.
i need add clause that, every line /xsd:documentation
grandchild, appends text <xsd:documentation>foo</xsd:documentation>
. line:
/xsd:schema/xsd:element[@name="comment"]
becomes:
/xsd:schema/xsd:element[@name="comment"] | doc comment
thanks, matt
the solution simple:
.1. define xsd
namespace in stylesheet:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xsd="http://www.w3.org/2001/xmlschema" >
.2. change:
.//documentation
to
.//xsd:documentation
btw, wrong:
//xsd|//@*
there no element named xsd
in document. want:
//xsd:*|//@*
also, there no need use local-name()
on attributes, name()
ok.
second observation:
there nothing wrong alejandro's solution. applied provided xml document produces following correct output:
/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
Comments
Post a Comment