【问题标题】:Parse XSLT attribute as an array将 XSLT 属性解析为数组
【发布时间】:2020-08-05 15:23:03
【问题描述】:

我正在使用 XSLT 从 XML 创建 HTML 表单。表单是动态创建的。没有现成的teamplate。用户需要多少输入就可以多少。我想让它尽可能短,所以我使用属性来创建例如选择标签中的选项。问题是我不知道如何转换这个 XML:

<input mapTo="dropdown" nameId="sampleId" inputDomain="[a, b, c, d, e]" />

进入:

<select id="sampleId">
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    <option value="d">d</option>
    <option value="e">e</option>
</select>

我的问题正是inputDomain 属性。我可以修改一个更简单的方法,但我想将它保存在一个属性中(如数组)。可能吗?或者你有更方便的想法?

【问题讨论】:

  • 您想使用哪个 XSLT 处理器,哪个 XSLT 版本?如果使用XML作为数据格式,使用XSLT作为处理语言,那么SET:[a, b, c, d, e]应该代表什么样的XML结构或XSLT已知数据类型?
  • 正如我所说,我可以将其修改为例如[a, b, c, d, e]。我只想知道是否有任何方法可以在一个属性中提供多个选项。我也不受任何版本的严格约束。我对此很灵活。
  • 您在w3.org/TR/xml/#sec-attribute-types 中找到该表示吗?还是在w3.org/TR/xmlschema-2/#built-in-derived?以及您可以使用哪个 XSLT 处理器、哪个 XSLT 版本?
  • 嗯。我认为没有像我写的那样有代表性。正如我所说,我可以使用任何版本的 XSLT,只是为了让它工作。目前,我的 XSL 文件使用 &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;。因此,没有任何方法可以让一些字符串用逗号或 XML 属性中的任何内容分隔?
  • 有一个列表数据类型,如 NMTOKENS,但您部分依赖 DTD 或模式支持。当然,带有 XPath 2 功能的 XSLT 2 也有类似tokenize 的功能。使用 XSLT 1 处理器可能支持扩展功能来完成这项工作。但是,如果您的数据变得更复杂并且标记分隔符可以出现在您的数据值中,那么它就会失败。

标签: html xml forms parsing xslt


【解决方案1】:

如果您使用模式感知 XSLT 2 或 3(例如,使用 Saxon 9 或 10 EE),您可以将属性声明为类型 xs:NMTOKENS 并使用空格分隔列表:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="input">
    <xs:complexType>
      <xs:attribute name="inputDomain" type="xs:NMTOKENS" use="required"/>
      <xs:attribute name="mapTo" use="required" type="xs:NCName"/>
      <xs:attribute name="nameId" use="required" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

然后是样式表处理

<input mapTo="dropdown" nameId="sampleId" inputDomain="a b c d e" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd"/>

可以在属性上使用data 函数来获得一个标记序列:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    expand-text="yes"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:template match="input[@mapTo = 'dropdown']">
        <select id="{@nameId}">
            <xsl:for-each select="data(@inputDomain)">
                <option value="{.}">{.}</option>
            </xsl:for-each>
        </select>
    </xsl:template>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output method="html" indent="yes" html-version="5"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Example</title>
            </head>
            <body>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    考虑以下示例:

    XML

    <input mapTo="dropdown" nameId="sampleId" inputDomain="a,b,c,d,e" />
    

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="input">
        <select id="sampleId">
            <xsl:for-each select="tokenize(@inputDomain, ',')">
                <option value="{.}">
                    <xsl:value-of select="." />
                </option>
            </xsl:for-each>
        </select>
    </xsl:template>
    
    </xsl:stylesheet>
    

    结果

    <?xml version="1.0" encoding="UTF-8"?>
    <select id="sampleId">
       <option value="a">a</option>
       <option value="b">b</option>
       <option value="c">c</option>
       <option value="d">d</option>
       <option value="e">e</option>
    </select>
    

    演示http://xsltfiddle.liberty-development.net/3MvmXiL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 2022-01-04
      • 2015-07-23
      • 2012-03-29
      • 2015-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多