【发布时间】:2011-09-02 14:01:58
【问题描述】:
这是我的原始 XML 文件:
<?xml version="1.0" encoding="windows-1250"?>
<CONTACTS>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>nuraaa_iceee@yahoo.co.in</EMail>
</CONTACT>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>nuraaa_iceee@gmail.com</EMail>
</CONTACT>
<CONTACT>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<EMail>KUMARg_8111@yahoo.com</EMail>
</CONTACT>
<CONTACT>
<FirstName>MarbellaFunkybuddha</FirstName>
<LastName>Funkybuddha Marbella</LastName>
<URL>http://www.facebook.com/profile.php?id=111123301493096451</URL>
</CONTACT>
<CONTACT>
<FirstName>Rangarajkarthik</FirstName>
<LastName>karthik Rangaraj</LastName>
<EMail>kart200006@gmail.com</EMail>
<EMail>karthikrangaraju@yahoo.com</EMail>
</CONTACT>
<CONTACT>
<FirstName>Rangaraj</FirstName>
<LastName>karthik </LastName>
<EMail>kart200006@gmail.com</EMail>
<EMail>karthikrangaraju@yahoo.com</EMail>
</CONTACT>
</CONTACTS>
如果我在 Firefox XUL 中使用 XSLT 处理器一个一个地执行,我有 4 个 XSl 文件可以完美运行。当我同时执行所有 XSL 文件时,它不会生成最终输出。
如果我一一使用 XSL 文件,这是上述 XML 文件的实际输出:
<?xml version="1.0" encoding="UTF-8"?>
<CONTACTS>
<CONTACT>
<CUS-ID>PDE-ID2</CUS-ID>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<gmail>nuraaa_iceee@gmail.com</gmail>
<yahoo>nuraaa_iceee@yahoo.co.in</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
<CONTACT>
<CUS-ID>PDE-ID4</CUS-ID>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<gmail/>
<yahoo>KUMARg_8111@yahoo.com</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
<CONTACT>
<CUS-ID>PDE-ID6</CUS-ID>
<FirstName>MarbellaFunkybuddha</FirstName>
<LastName>Funkybuddha Marbella</LastName>
<gmail/>
<yahoo/>
<URL>http://www.facebook.com/profile.php?id=111123301493096451</URL>
<Facebook-ID>1123301493096451</Facebook-ID>
</CONTACT>
<CONTACT>
<CUS-ID>PDE-ID12</CUS-ID>
<FirstName>Rangarajkarthik</FirstName>
<LastName>karthik Rangaraj</LastName>
<gmail>kart200006@gmail.com</gmail>
<yahoo>karthikrangaraju@yahoo.com</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
</CONTACTS>
这是在XUL中调用XSl文件的实际JS函数:
function process()
{
var src = readFile("D:\\createXML2.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, "D:\\aout30.xml");
//alert('New Contact updated successfully');
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
prompts.alert(null, "Final creation", "Final creation is done");
process2();
}
这些是我用来生成最终输出的 XSL 文件:
文件 1:合并具有相同 FN 和 LN 的联系人
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="groupName" match="//CONTACTS/CONTACT" use="concat(FirstName, LastName)" />
<xsl:template match="CONTACTS">
<CONTACTS>
<xsl:for-each select="//CONTACTS/CONTACT[generate-id() = generate-id( key('groupName', concat(FirstName, LastName)) [1] ) ]" >
<xsl:sort select="CONTACT/EMail" />
<xsl:call-template name="group">
<xsl:with-param name="k1" select="FirstName" />
<xsl:with-param name="k2" select="LastName" />
</xsl:call-template>
</xsl:for-each>
</CONTACTS>
</xsl:template>
<xsl:template name="group">
<xsl:param name="k1" />
<xsl:param name="k2" />
<CONTACT>
<xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][1]">
<xsl:copy-of select="FirstName" />
<xsl:copy-of select="LastName" />
<!-- here we have the first Email -->
<xsl:copy-of select="EMail" />
</xsl:for-each>
<xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][position() > 1]">
<!-- here we have the next Email -->
<xsl:copy-of select="EMail" />
</xsl:for-each>
<xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][position() > 2]">
<!-- here we have the next Email -->
<xsl:copy-of select="EMail" />
</xsl:for-each>
<xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][position() > 3]">
<!-- here we have the next Email -->
<xsl:copy-of select="EMail" />
</xsl:for-each>
<xsl:copy-of select="URL" />
</CONTACT>
</xsl:template>
</xsl:stylesheet>
File2:合并不同联系人的相同电子邮件地址
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="k_ContactsByEmail"
match="CONTACTS/CONTACT"
use="EMail"/>
<xsl:template match="CONTACTS">
<xsl:copy>
<xsl:apply-templates select="CONTACT[generate-id()=
generate-id(key('k_ContactsByEmail',EMail)[1])]
|
CONTACT[not(EMail)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CONTACT">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="
key('k_ContactsByEmail', EMail)/*
[not(.=current()/*)]
[not(self::FirstName or self::LastName)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
文件 3:文件 3 用于根据域类型分隔电子邮件值
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CONTACT">
<xsl:copy>
<xsl:copy-of select="FirstName|LastName|URL"/>
<Facebook-ID><!-- To extract the ID value from URL/Email -->
<xsl:choose>
<xsl:when test="URL">
<xsl:value-of select="substring-after(URL,'?id=')"/>
</xsl:when>
<xsl:otherwise>
<!-- <xsl:value-of select="substring-before(EMail[1],'@')"/>-->
</xsl:otherwise>
</xsl:choose>
</Facebook-ID>
<EMAILS>
<xsl:apply-templates select="EMail"/>
</EMAILS>
</xsl:copy>
</xsl:template>
<xsl:template match="EMail">
<EMail> <!-- To extract the Emails based on domain value from EMAIL -->
<Type><xsl:value-of select="substring-before(
substring-after(.,'@'),
'.')"/>
</Type>
<Value><xsl:value-of select="."/></Value>
</EMail>
</xsl:template>
</xsl:stylesheet>
文件 4:为每个联系人生成客户 ID,并将电子邮件域标签添加到来自第三个 xsl 生成的输出文件的电子邮件值类型。
<?xml version="1.0" encoding="UTF-8"?>
<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>
<CUS-ID>
<xsl:apply-templates select="." mode="generate-id"/>
</CUS-ID>
<FirstName>
<xsl:value-of select="FirstName"/>
</FirstName>
<LastName>
<xsl:value-of select="LastName"/>
</LastName>
<gmail>
<xsl:value-of select="EMAILS/EMail[Type='gmail']/Value"/>
</gmail>
<yahoo>
<xsl:value-of select="EMAILS/EMail[Type='yahoo']/Value"/>
</yahoo>
<URL>
<xsl:value-of select="URL"/>
</URL>
<Facebook-ID>
<xsl:value-of select="Facebook-ID"/>
</Facebook-ID>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="generate-id">
<xsl:text>PDE-ID</xsl:text>
<xsl:number level="any" count="node()" format="10000"/>
</xsl:template>
</xsl:stylesheet>
有时它会生成正确的输出,但大多数时候它不起作用。 我真的不明白可能是什么问题。是否有可能将所有这些 SL 文件合并为一个文件?请帮我。谢谢。
【问题讨论】:
-
当它“不工作”时究竟会发生什么?从您的 JS 代码中,我了解到您有 3 个中间结果和最终结果。我猜“同时一个接一个”意味着您删除了 alert() 调用。您是否在错误控制台中看到任何消息和/或您是否注意到中间结果有任何问题? readFile() 和 saveFile() 是什么样的?如果您从文件中读取的字符串与中间结果一起记录会发生什么?
-
@Nickolay :通常 readFile() 和 saveFile() 是用于读取 XSL 文件并将 XML 文件另存为 Firefox 建议的 prettyString 的 javascript 函数。有时会发生什么,任何一个 XSL 文件都没有给出正确的输出,因此下一个 XSL 文件将无法正常工作。 Firefox 错误控制台不会出现错误。有没有办法将所有这些 XSL 文件合并为一个文件?
标签: javascript xml xul xslt