如何在XSD中使用注释将XML整数映射到相关描述?

时间:2010-07-01 08:27:40

标签: xml xslt xsd

我正在编写一个XSLT,用于将XML文件转换为人类可读的HTML页面。

XML有几个字段来描述数据的某些方面,其中包含表示映射字符串的整数。整数不是用户想要的信息,我需要将这些整数映射到相应的字符串。

映射的字符串在XSD中的注释中可用。

例如:

<typewoning>1</typewoning>

遵循XSD声明:

<xs:element name="typewoning" type="TypeWoningEnum"/>

地图:

    <xs:simpleType name="TypeWoningEnum">
    <xs:restriction base="xs:integer">
        <xs:enumeration value="1">
            <xs:annotation>
                <xs:documentation>vrijstaande woning</xs:documentation>
            </xs:annotation>
        </xs:enumeration>
        <xs:enumeration value="2">
            <xs:annotation>
                <xs:documentation>twee-onder-een-kap/rijwoning hoek</xs:documentation>
            </xs:annotation>
        </xs:enumeration>

等等

所以在这种情况下,我想显示值为1的注释,它应该是'vrijstaan​​de woning'。

接近这个的最佳方法是什么?我在XML / XSLT中没有经验可以知道任何这些解决方案,而且我的谷歌搜索没有任何用处。

提前致谢。

2 个答案:

答案 0 :(得分:3)

如果我读得正确,那么你想要做的事情并不是直截了当的。 XML文档和模式之间没有“神奇”的连接,您必须在样式表中加载模式并在其中查找文档。

假设在某个时刻您的XSLT样式表处于typewoning位于上下文元素下的位置(即value-of select="typewoning"将输出其值),您可以这样做:

<xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/>

<xsl:variable name="type" select="$schema//xsd:simpleType[@name = 'TypeWoningEnum']"/>

<xsl:variable name="value" select="$type//xsd:enumeration[@value = typewoning]//xsd:documentation"/>

<xsl:value-of select="$value"/>

一些解释:

  1. 第一步使用XSL文档函数
  2. 将架构加载到变量中
  3. 第二步找到正确的类型(你可能会变得更漂亮,并在文档中使用元素的类型找到类型,但是必须打开模式验证,你需要一个符合模式的XSLT引擎)
  4. 第三步,根据typewoning元素的内容找到要输出的文档值。
  5. 第四步写出结果,按你的意愿使用。

    编辑,如果您愿意使用符合架构的XSLT引擎,例如付费版本saxon,则可以选择。假设所有枚举都来自integer,您可以在某个父节点的上下文中尝试:

    <xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/>
    
    <xsl:for-each select="element(*, xsd:integer)">
        <xsl:variable name="type" select="$schema//xsd:simpleType[@name = local-name(current())]"/>
    
        <xsl:if test="$type">
            <xsl:variable name="value" select="$type//xsd:enumeration[@value = current()/text()]//xsd:documentation"/>
    
            <xsl:text>Value: </xsl:text> <xsl:value-of select="$value"/>
        </xsl:if>
    </xsl:for-each>
    

答案 1 :(得分:2)

我已经投入了一些时间和精力,我决定编写一个XSLT,将模式转换为基于每个xs:simpleType中的枚举文档的映射。

此代码:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">

<xsl:output method="xml" version="1.0"
    encoding="utf-8" indent="yes"/>

<xsl:strip-space elements="*"/>

<xsl:template match="xs:schema">
    <mappings>
        <xsl:for-each select="//xs:element[contains(@type, 'Enum')] | //xs:element[contains(@type, 'JaNee')]">
            <xsl:variable name="type" select="@type" />
            <xsl:element name="{concat(@name, 'Mapping')}" >
                <xsl:apply-templates select="//xs:simpleType[@name=$type]">
                    <xsl:with-param name="elemname" select="@name" />
                </xsl:apply-templates>
            </xsl:element>
        </xsl:for-each>
    </mappings>
</xsl:template>

<xsl:template match="xs:enumeration">
    <xsl:param name="elemname" select="'undefined'" />
    <xsl:element name="{$elemname}">
        <xsl:attribute name="value">
            <xsl:value-of select="@value" />
        </xsl:attribute>
        <xsl:value-of select="xs:annotation/xs:documentation" />
    </xsl:element>
</xsl:template>

完全按照我的希望输出:

    ...snip...
   <typewoningMapping>
      <typewoning value="1">vrijstaande woning</typewoning>
      <typewoning value="2">twee-onder-een-kap/rijwoning hoek</typewoning>
      <typewoning value="3">rijwoning tussen</typewoning>
      <typewoning value="4">galerijflat (hoogbouw)</typewoning>
      <typewoning value="5">portiekflat (etage)</typewoning>
      <typewoning value="6">maisonnettewoning</typewoning>
      <typewoning value="7">flatwoning (overig)</typewoning>
      <typewoning value="8">woongebouw met niet-zelfstandige woonruimte</typewoning>
   </typewoningMapping>
   ...snip...

现在,我只需要编写一些内容,使用为我想要使用的映射定义的xsl:key标记创建xsl。

感谢所有人一路上帮助我。