Xml 用XSL生成id系统
如果可能的话,我需要编写一个XSL文件来转换与此类似的XML语法Xml 用XSL生成id系统,xml,xslt,Xml,Xslt,如果可能的话,我需要编写一个XSL文件来转换与此类似的XML语法 <media address="1234 A St."> <book title="My Book" isbn="1324-1123-1456-1566" /> <book title="Your Book" isbn="1232-1123-1456-1566" /> </media> 变成这样的格式 <library> <informati
<media address="1234 A St.">
<book title="My Book" isbn="1324-1123-1456-1566" />
<book title="Your Book" isbn="1232-1123-1456-1566" />
</media>
变成这样的格式
<library>
<information>
<building id="1">
<address>1234 A St.</address>
</building>
</information>
<medialist>
<book_definitions>
<book_definition id="2" />
<book_definition id="3" />
</book_definitions>
<book_metadata>
<metadata id="4">
<isbn>1324-1123-1456-1566</isbn>
<book_definition_id>2</book_definition_id>
</metadata>
<metadata id="5">
<isbn>1232-1123-1456-1566</isbn>
<book_definition_id>3</book_definition_id>
</metadata>
</book_metadata>
<book_instances>
<book_instance id="6">
<book_definition_id>2</book_definition_id>
<book_metadata_id>4</book_metadata_id>
<title>My Book</title>
</book_instance>
<book_instance id="7">
<book_definition_id>2</book_definition_id>
<book_metadata_id>5</book_metadata_id>
<title>Your Book</title>
</book_instance>
</book_instances>
</medialist>
</library>
1234 A街。
1324-1123-1456-1566
2.
1232-1123-1456-1566
3.
2.
4.
我的书
2.
5.
你的书
我意识到目标格式有点复杂,但我无法控制它
我已经成功地编写了XSL,以使用模板模式正确地转换大多数XML标记。即
<xsl:template match="/media/book" mode="definitions">
<xsl:template match="/media/book" mode="metadata">
<xsl:template match="/media/book" mode="instance">
然而,我一直在尝试使用或其他一些技巧来正确生成id,但收效甚微
目标格式对id有两个约束:每个id属性(无规则)的名称必须是唯一的。一旦排序,ID必须是连续的,但它们可以以目标格式的任何顺序出现,即(1,2,3,4,5)和(5,2,3,1,4)都可以接受,但(1,2,4,5,6)不可以
有没有办法通过XSL实现这一点?在我看来,因为(除了建筑之外),您总是为每种不同的“类型”节点为每本书生成一个ID,所以您可以通过根据公式生成ID来保证唯一和连续的ID。如果你有N本书,那么你可以“命令”它
- 该建筑始终为id 1
- 书籍m的
始终是book\u定义
(因此从2运行到N+1)1+m
- 图书m的元数据是
(N+1)+m
- 实例是
(2N+1)+m
如果您在任何地方都遵循此方案,您只需计算适当的交叉引用
图书定义\u id
等,而无需查找表。虽然我刚刚注意到Ian Roberts已经解释了此方法,但我已经准备为此编写XSLT,因此我将发布它-遵循XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<library>
<xsl:apply-templates />
</library>
</xsl:template>
<xsl:template match="media">
<xsl:variable name="current">
<xsl:number />
</xsl:variable>
<information>
<building>
<xsl:attribute name="id">
<xsl:value-of select="$current" />
</xsl:attribute>
<address>
<xsl:value-of select="@address" />
</address>
</building>
</information>
<medialist>
<book_definitions>
<xsl:apply-templates mode="definition">
<xsl:with-param name="current">
<xsl:value-of select="$current" />
</xsl:with-param>
</xsl:apply-templates>
</book_definitions>
<book_metadata>
<xsl:apply-templates mode="metadata">
<xsl:with-param name="current">
<xsl:value-of select="$current" />
</xsl:with-param>
</xsl:apply-templates>
</book_metadata>
<book_instances>
<xsl:apply-templates mode="instances">
<xsl:with-param name="current">
<xsl:value-of select="$current" />
</xsl:with-param>
</xsl:apply-templates>
</book_instances>
</medialist>
</xsl:template>
<xsl:template match="book" mode="definition">
<xsl:param name="current" />
<book_definition id="{(position() + $current)}" />
</xsl:template>
<xsl:template match="book" mode="metadata">
<xsl:param name="current" />
<metadata id="{(position() + $current + count(parent::media/book))}">
<isbn>
<xsl:value-of select="@isbn" />
</isbn>
<book_definition_id>
<xsl:value-of select="position() + $current" />
</book_definition_id>
</metadata>
</xsl:template>
<xsl:template match="book" mode="instances">
<xsl:param name="current" />
<book_instance id="{(position() + 2*count(parent::media/book) + $current)}">
<book_definition_id>
<xsl:value-of select="position() + $current" />
</book_definition_id>
<book_metadata_id>
<xsl:value-of select="position() + $current + count(parent::media/book)" />
</book_metadata_id>
<title>
<xsl:value-of select="@title" />
</title>
</book_instance>
</xsl:template>
</xsl:transform>
元数据id是当前书籍、当前/父媒体
元素的所有书籍和当前
元素的位置的总和:
<book_definition id="{(position() + $current)}" />
<metadata id="{(position() + $current + count(parent::media/book))}">
你确定你真的需要第二个约束吗?要使输出节点链接到输入中不存在的其他输出节点将非常困难(人们应该正确地问,为什么您也需要这样做)。不幸的是,我确实需要第二个约束。然而,假设我没有这样做,有没有一种方法可以使用XSL只满足第一个约束?还有一种方法可以满足第二个约束。真正的问题是你愿意为此付出多少努力。你和那些试图帮助你的人。一、 首先,我觉得这项任务没有意思,因为我看不出这对任何事情都有什么帮助。您的标题谈到主键/外键;好吧,除了这些书已经有一个唯一且永久的ISBN这一事实之外,很明显,books(你称之为book_definitions)是父表,所有其他表都应该链接到它,而不是以级联方式彼此链接。也许你对标题的看法是正确的。我改了。至于示例XML,我不能发布实际的格式,因为它包含专有信息,我选择使用一些常见的东西来模拟该格式。不幸的是,我无法控制目标格式,必须符合他们不寻常的标准。请相信这些要求与我描述的一样。至于你的不感兴趣,谢谢你的评论,但我非常感谢任何愿意进一步帮助我的人。
<metadata id="{(position() + $current + count(parent::media/book))}">
<book_instance id="{(position() + 2*count(parent::media/book) + $current)}">