1

我正在尝试从 Relax NG XML 模式中的注释生成非常简单的文档。例如,给定以下松弛 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 文档工具。我玩过 rng to docbook 样式表,但它没有做我想要的。据我所知,它只是单独列出了元素,没有关于 XPath 的详细信息。我不知道如何将其用作获得我所追求的输出的起点。

给定提供的 RelaxNG 示例,是否可以(如果可以,如何?)使用 XSLT 生成这种类型的文档输出?

虽然 XSLT 是理想的,但它不是必需的。我愿意接受任何可以完成工作的事情。

4

1 回答 1

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>&#10;</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>&#10;</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>&#10;</xsl:text>            
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
于 2012-05-08T19:40:27.870 回答