这是我的XML文件,如果我运行XSLt文件,我将在Eclipse XSL Transformation中以相同的顺序获得相同的输出。
即使向我的xml文件添加新记录并运行XSL文件,<xsl:value-of select="generate-id(.)"/>
也会为新记录创建唯一ID。
<?xml version="1.0" encoding="UTF-8"?>
<CONTACTS>
<CONTACT>
<Customer-ID>N65539</Customer-ID>
<FirstName>Ben</FirstName>
<LastName>Foden</LastName>
<email></email>
<address></address>
<state>AZ</state>
<country>US</country>
</CONTACT>
<CONTACT>
<Customer-ID>N65539</Customer-ID>
<FirstName>Nimal</FirstName>
<LastName>Anup</LastName>
<email>nimal.anup@gmail.com</email>
<address></address>
<state>TN</state>
<country>IN</country>
</CONTACT>
<CONTACTS>
这是我更新的XSLT文件:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<!--Identity template to copy content forward-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="CONTACT">
<xsl:copy>
<Customer-ID>
<xsl:apply-templates select="node()" mode="generate-id"/>
</Customer-ID>
<FirstName>
<xsl:value-of select="FirstName"/>
</FirstName>
<LastName>
<xsl:value-of select="LastName"/>
</LastName>
<email>
<xsl:value-of select="email"/>
</email>
<address>
<xsl:value-of select="address"/>
</address>
<state>
<xsl:value-of select="state"/>
</state>
<country>
<xsl:value-of select="country"/>
</country>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="generate-id">
<xsl:text>N</xsl:text>
<xsl:number level="single" count="node()" format="100"/>
</xsl:template>
</xsl:stylesheet>
然后我在XUL中为XSLT处理器函数使用了相同的XSLT文件,我得到了不同类型的ID和输出。 它会继续为旧记录和新记录生成新ID如果我在XML文件中添加新记录。
如何仅为新记录生成新ID?如何将输入文件的XML模板与我的XML输出文件相同。
这是我得到的输出:
<?xml version="1.0" encoding="UTF-8"?>
<CONTACTS>
<CONTACT><Customer-ID>id0x03e4a620</Customer-ID><FirstName>Ben</FirstName><LastName>Foden</LastName><email></email><address></address><state>AZ</state><country>US</country></CONTACT>
<CONTACT><Customer-ID>id0x03e4ad80</Customer-ID><FirstName>Nimal</FirstName><LastName>Anup</LastName><email>nimal.anup@gmail.com</email><address></address><state>TN</state><country>IN</country></CONTACT>
<CONTACTS>
这是我调用XSLT文件的Javascript:脚本在保存XML文件后调用此函数。新记录的更新方式与输入xml文件中提到的相同。
function process()
{
var src = readFile("c:\\idgenerator.xsl");
var parsed = (new DOMParser()).parseFromString(src, "text/xml");
var stylesheet = parsed.documentElement;
var processor = new XSLTProcessor();
processor.importStylesheet(stylesheet );
objXMLDoc = processor.transformToDocument(objXMLDoc);
var serializer = new XMLSerializer();
var prettyString = serializer.serializeToString(objXMLDoc);
saveFile(prettyString, "C:\\mercredi.xml");
}
非常感谢。
答案 0 :(得分:3)
如果generate-id()在不同的运行中产生可重复的结果,那么这是您的XSLT处理器设计的意外,而不是您可以依赖的行为。
答案 1 :(得分:2)
我不知道Eclipse使用的是什么XSLT处理器。至少在某些扩展程序中,您可以配置处理器,例如到Xalan或Saxon。 Mozilla / XUL至少在默认情况下使用Transformiix。我在某处读到可以使用Saxon。 不同的XSLT处理器之间肯定存在差异。
generate-id()的规范没有说明生成的ID应该是什么样的;只是他们“必须由ASCII字母数字字符组成,并且必须以字母字符开头”。
如果您希望XSLT-under-XUL生成与Eclipse相同类型的ID,那么您有几个选项。
1)您可以尝试让XUL使用Eclipse使用的XSLT处理器。我不知道这是否可能。
2)实施您自己的自定义模板以生成ID。
使用后者,如果你有一些基于它们的稳定数据,那么模仿你在Eclipse中获得的ID的风格并使它们在多个运行和不同的XSLT处理器中保持稳定并不难。
例如,如果您的记录顺序始终稳定(旧记录永远不会被删除,交换或替换),那么您可以使用这样的模板来生成ID:
<xsl:template match="node()" mode="generate-id">
<xsl:text>N</xsl:text>
<xsl:number level="any" count="node()" format="00001"/>
</xsl:template>
如果订单不稳定,但名字+姓氏既稳定又独特,您可以使用
<xsl:template match="node()" mode="generate-id">
<xsl:value-of select="concat(FirstName, LastName)" />
</xsl:template>
答案 2 :(得分:0)
generate-id()以这种方式工作,您可以在使用generate-id()之前验证联系人中是否有Customer-ID ...
<xsl:if test="./Customer-Id=''"> <!-- if the new contact comes with this empty -->
<Customer-ID>
<xsl:value-of select="generate-id(.)"/>
</Customer-ID>
<xsl:if>
<xsl:if test="not(./Customer-Id='')"> <!-- if the contact comes with Customer-Id -->
<Customer-ID>
<xsl:value-of select="Customer-Id"/>
</Customer-ID>
<xsl:if>