- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 XSLT 将 XSD 方案(转换为 C++ 类)。我目前遇到的问题是我想根据依赖项对 complexType 条目重新排序。 IE。如果 complexType Type1 包含 complexType Type2 的属性,我希望 Type2 在输出中出现在 Type1 之前(出于显而易见的原因 - 在 C++ header 中,如果 Type2 在 Type1 之后定义,则 Type2 不能用于声明 Type1 中的属性)。
示例输入 XSD 文件:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Type1">
<xs:sequence>
<xs:element name="id" type="xs:short" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Type2">
<xs:sequence>
<xs:element name="id" type="xs:short" />
<xs:element name="value" type="Type3" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Type3">
<xs:sequence>
<xs:element name="id" type="xs:short" />
<xs:element name="value" type="Type4" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Type4">
<xs:sequence>
<xs:element name="id" type="xs:short" />
</xs:sequence>
</xs:complexType>
</xs:schema>
到目前为止我管理的是这个 XSLT(这是一个简化的例子,只是生成类型名称排序,而不是实际的类):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text" encoding="utf-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template name="gen-type-list">
<xsl:param name="name"/>
<xsl:value-of select="concat('[', $name, ']')"/>
</xsl:template>
<!--
Generate the type order according to dependencies
Dependency should come before the dependent type.
-->
<xsl:template name="gen-type-order">
<xsl:param name="name"/>
<xsl:param name="typeList"/>
<xsl:for-each select="xs:attribute | xs:complexContent/xs:extension//xs:attribute | xs:sequence/xs:element | xs:complexContent/xs:extension/xs:sequence/xs:element">
<xsl:variable name="typeEntry">
<xsl:value-of select="concat('[', @type, ']')"/>
</xsl:variable>
<xsl:if test="contains($typeList, $typeEntry)">
<xsl:value-of select="$typeEntry"/>
</xsl:if>
</xsl:for-each>
<xsl:value-of select="concat('[', $name, ']')"/>
</xsl:template>
<!--
Print the ordered listing (line by line)
-->
<xsl:template name="print-type-order">
<xsl:param name="typeList"/>
<xsl:choose>
<xsl:when test="not(contains($typeList, ']['))">
<xsl:value-of select="substring-after(substring-before($typeList, ']'), '[')"/>
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after(substring-before($typeList, ']'), '[')"/>
<xsl:text>
</xsl:text>
<xsl:call-template name="print-type-order">
<xsl:with-param name="typeList" select="substring-after($typeList, ']')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
The main processing template handling the entire document
-->
<xsl:template match="/xs:schema">
<xsl:variable name="typeList">
<xsl:for-each select="xs:complexType">
<xsl:call-template name="gen-type-list">
<xsl:with-param name="name" select="@name"/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$typeList"/>
<xsl:text>
</xsl:text>
<xsl:variable name="typeOrder">
<xsl:for-each select="xs:complexType">
<xsl:call-template name="gen-type-order">
<xsl:with-param name="name" select="@name"/>
<xsl:with-param name="typeList" select="$typeList"/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:call-template name="print-type-order">
<xsl:with-param name="typeList" select="$typeOrder"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
在示例 XSD 上运行的输出如下:
[Type1][Type2][Type3][Type4]
Type1
Type3
Type2
Type4
Type3
Type4
第一行只是所有类型的简单列表(用于调试目的,用于实际检查类型是否为 gen-type-order
模板中的复杂类型)。这已经很接近我想要的了,应该是:
Type1
Type4
Type3
Type2
我挣扎的是:
<xsl:if test="//xs:complexType[name = @type]"
的东西,但那没有用)事实上,最简单的方法是重新排序 XSD 本身,不幸的是,XSD 不在我的控制之下,因此很难管理它。
注意:我知道有一些工具可以将 XSD 转换为 C++,例如 Code Synthesis xsdcxx,但我更喜欢使用 XSLT,因为大多数工具都依赖于其他库,例如 Xerces,而我不需要这些库也不想要(除了工具本身的许可问题)。并且在未来我想使用类似的 XSLT 来转换为不同的输出类型(例如 Thrift 消息文件)。
//编辑
我刚刚通过使用以下方法解决了第 3) 点:
<xsl:template name="gen-type-order">
<xsl:param name="name"/>
<xsl:for-each select="xs:attribute | xs:complexContent/xs:extension//xs:attribute | xs:sequence/xs:element | xs:complexContent/xs:extension/xs:sequence/xs:element">
<xsl:variable name="typeEntry">
<xsl:value-of select="concat('[', @type, ']')"/>
</xsl:variable>
<xsl:variable name="typeName">
<xsl:value-of select="@type"/>
</xsl:variable>
<xsl:if test="//xs:complexType[@name = $typeName]">
<xsl:value-of select="$typeEntry"/>
</xsl:if>
</xsl:for-each>
<xsl:value-of select="concat('[', $name, ']')"/>
</xsl:template>
但其他点仍然存在。
最佳答案
在 XSLT 2.0 中,以正确的顺序排列事物并不难。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text" encoding="utf-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:key name="type" match="xs:complexType" use="@name"/>
<!-- Returns value 1 if there are no dependencies, 2 if there's 1 etc. -->
<xsl:template match="*" mode="get-dependency-depth">
<xsl:param name="depthSummands" as="xs:integer*">
<xsl:apply-templates mode="get-dependency-depth"
select="key('type', (
xs:attribute | xs:complexContent/xs:extension//xs:attribute |
xs:sequence/xs:element | xs:complexContent/xs:extension/xs:sequence/xs:element
)/@type)"/>
</xsl:param>
<xsl:copy-of select="sum($depthSummands) + 1"/>
</xsl:template>
<xsl:template match="*" mode="process-types">
<xsl:value-of select="concat(@name, ' (dependency depth: ')"/>
<xsl:apply-templates mode="get-dependency-depth" select="."/>
<xsl:value-of select="') '"/>
</xsl:template>
<xsl:template match="/xs:schema">
<xsl:apply-templates select="xs:complexType" mode="process-types">
<xsl:sort data-type="number">
<xsl:apply-templates mode="get-dependency-depth" select="."/>
</xsl:sort>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
应用于输入 XML 时的输出:
Type1 (dependency depth: 1)
Type4 (dependency depth: 1)
Type3 (dependency depth: 2)
Type2 (dependency depth: 3)
这既不会测试循环依赖,也不会对大型依赖树特别有效 - 对于那些有依赖深度缓存之类的东西会很有用。
关于xslt - XSLT : How to reorder entries according to the dependencies 的 XSD 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39141991/
我有一个 XSLT 样式表,如下所示: 我想使用第二个 XSLT 样式表来转换此样式表,以删除与 XQHead
我们有一个大型 xslt,可以呈现整个商店区域,包括产品、制造商,并根据价格和类别进行过滤。我使用 sitecore 作为 CMS,但遇到缓存问题。我有大约 9000 个项目,有些页面需要长达 20
我想根据条件的结果应用具有不同参数的模板。像这样: Attribute no. 1
我有一些看起来像这样的 XML Foo Details Bar Details Baz Details Foo Blah Bar BlahBlah Baz BlahBlahBl
我试图从这种输入出发: a b c d e f g ... 使用 XSLT 的 HTML 输出: one two a e b f
我想知道如何在 xslt 中找到特定节点的第一个子节点名称。 我有一个 xml: some text 我可以使用 body/
是否可以在 XSLT 中获取上个月的最后一天?我找到了这个函数:http://www.xsltfunctions.com/xsl/functx_last-day-of-month.html但我不确定如
具有特定节点的匹配元素存在问题。 xml: description of profile PhoneKeyPad S
我将一堆键值对作为参数传递给 XSL(日期 ->“1 月 20 日”,作者 ->“Dominic Rodger”,...)。 我正在解析的一些 XML 中引用了这些 - XML 如下所示: 目前,除
我找不到这个问题的确切答案,所以我希望有人能在这里帮助我。 我有一个字符串,我想在最后一个 '.' 之后获取子字符串。我正在使用 xslt 1.0。 这是怎么做的?这是我的代码。
我在尝试找出 xslt 上的 var 范围时遇到问题。我实际上想要做的是忽略具有重复“旅游代码”的“旅行”标签。 示例 XML: X1 Budapest X1 Budapest X
我有一些数据在 xslt 的 for-each 循环中输出。我对列表进行了分页,但没有对排序选择器进行分页。 用户应该能够对 2 个值(创建的数据和每个项目的数字字段)进行排序。默认的排序方法是创建日
我有一个奇怪的要求。 我在 xslt 中有一个包含月份的变量,带有它们的 id (1-12) 问题是我需要全部显示它们,但从一月(1)以外的月份开始。 目前我有以下 JAN
如何在 xslt 转换中模块化一组重复的输出?例如,我有如下内容(伪代码)。 并
我得到一个像这样的字符串。 13091711111100222222003333330044444400 字符串的模式是这样的 13 - 09 - 17 - 11111 - 100 - 22222 -
我是 XSLT 的新手,有一个一般性问题。为了区分具有不同属性的两个元素,最好(也是为了性能)使用 和 而不是 在一个模板中。据我所知,这就是 XSLT 中应该“思考”的方式。但在我看来,这有一个缺点
如何从“19650512-0065”到“196505120065”这样的字符串中删除连字符 使用这个模板:传递 theID =
是否有任何功能可以在左侧填充零? 我正在尝试做的要求是: 我们不知道即将到来的输入字符串长度。 如果小于 20,我们必须在左侧填充零。 如果输入字符串长度为 10,那么我们必须在左侧填充 10 个零。
身份模板如下所示: 是否选择多于 ,或者身份模板可能是这样的? 当我执行以下操作时,究竟选择了什么? 最佳答案
我正在尝试使用 XML 信息和 XSLT 模板创建超链接。这是 XML 源代码。 Among individual stocks, the top percentage gainers in the
我是一名优秀的程序员,十分优秀!