我正在尝试从Relax NG XML Schema中的注释生成非常简单的文档。例如,给出以下Relax NG:
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element name="topNode">
<ref name="topNode-ref"/>
</element>
</start>
<define name="topNode-ref">
<a:documentation>This is the top of the doc.</a:documentation>
<oneOrMore>
<element name="level1">
<ref name="level1-ref"/>
</element>
</oneOrMore>
</define>
<define name="level1-ref">
<a:documentation>Here's some notes about level1.</a:documentation>
<attribute name="att1">
<a:documentation>Details about att1.</a:documentation>
</attribute>
<element name="subLevel2">
<ref name="subLevel2-ref"/>
</element>
</define>
<define name="subLevel2-ref">
<a:documentation>Notes on subLevel2.</a:documentation>
<attribute name="subAtt"/>
<zeroOrMore>
<element name="subLevel3">
<ref name="subLevel3-ref"/>
</element>
</zeroOrMore>
</define>
<define name="subLevel3-ref">
<a:documentation>And here is subLevel3.</a:documentation>
<attribute name="subSubAtt"/>
</define>
</grammar>
将用于验证XML文件,例如:
<?xml version="1.0" encoding="UTF-8"?>
<topNode>
<level1 att1="some test">
<subLevel2 subAtt="more text"></subLevel2>
</level1>
<level1 att1="quick">
<subLevel2 subAtt="brown">
<subLevel3 subSubAtt="fox"></subLevel3>
</subLevel2>
</level1>
</topNode>
我希望能够生成列出每个元素/属性的基本XPath的文档,然后显示任何相应的文档注释。例如:
/topNode
This is the top of the doc.
/topNode/level1
Here's some notes about level1
/topNode/level1/@att1
Details about att1.
etc...
最后,我将添加更多关于“zeroOrMore”,可能的数据类型等的文档......但我需要先解决第一步。
我找到了Techquila RELAX-NG Documentation Tools。我已经玩过rng到docbook样式表,但它没有做我正在寻找的东西。它只是单独列出元素,没有关于XPath的详细信息,据我所知。我不知道如何将它作为起点来获得我想要的输出。
在提供RelaxNG示例的情况下,是否有可能(如果是这样,如何?)使用XSLT生成此类文档输出?
虽然XSLT是理想的,但它不是必需的。我完全可以完成任务。
答案 0 :(得分:2)
这将适用于像你的例子一样非常简单的语法。
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:r="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
>
<xsl:output method="text" />
<xsl:template match="/">
<xsl:apply-templates select="//r:define[a:documentation] | //r:attribute[a:documentation]" />
</xsl:template>
<xsl:template match="r:define">
<xsl:variable name="doc" select="a:documentation" />
<xsl:call-template name="print-path">
<xsl:with-param name="elm" select="//r:element[r:ref/@name=current()/@name]" />
</xsl:call-template>
<xsl:value-of select="$doc" /><xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="r:attribute">
<xsl:variable name="doc" select="a:documentation" />
<xsl:call-template name="print-path">
<xsl:with-param name="elm" select="//r:element[r:ref/@name=current()/ancestor::r:define/@name]" />
<xsl:with-param name="path" select="concat('/@',@name)" />
</xsl:call-template>
<xsl:value-of select="$doc" /><xsl:text> </xsl:text>
</xsl:template>
<xsl:template name="print-path">
<xsl:param name="elm" />
<xsl:param name="path" />
<xsl:variable name="parent" select="//r:ref[@name=$elm/ancestor::r:define/@name]/ancestor::r:element" />
<xsl:message><xsl:value-of select="$elm/@name" /></xsl:message>
<xsl:choose>
<xsl:when test="$parent">
<xsl:call-template name="print-path">
<xsl:with-param name="elm" select="$parent" />
<xsl:with-param name="path" select="concat('/',$elm/@name,$path)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('/',$elm/@name,$path)" /><xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>