在 XUL JavaScript 中使用 XSLT 处理器的多个 XSL 文件
这是我的原始 XML 文件:
<?xml version="1.0" encoding="windows-1250"?>
<CONTACTS>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<EMail>[email protected]</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>[email protected]</EMail>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>Rangaraj</FirstName>
<LastName>karthik </LastName>
<EMail>[email protected]</EMail>
<EMail>[email protected]</EMail>
</CONTACT>
</CONTACTS>
我有 4 个 XSl 文件,如果我在 Firefox XUL 中使用 XSLT 处理器一一执行,这些文件可以完美运行。当我同时一一执行所有 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>[email protected]</gmail>
<yahoo>[email protected]</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
<CONTACT>
<CUS-ID>PDE-ID4</CUS-ID>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<gmail/>
<yahoo>[email protected]</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>[email protected]</gmail>
<yahoo>[email protected]</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 文件:
File1:合并具有相同 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>
文件 2:合并不同联系人的相同电子邮件地址
<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,并将电子邮件域标签添加到生成的第 3 个 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 文件合并为一个文件?请帮我。谢谢。
This is my original XML file:
<?xml version="1.0" encoding="windows-1250"?>
<CONTACTS>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<EMail>[email protected]</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>[email protected]</EMail>
<EMail>[email protected]</EMail>
</CONTACT>
<CONTACT>
<FirstName>Rangaraj</FirstName>
<LastName>karthik </LastName>
<EMail>[email protected]</EMail>
<EMail>[email protected]</EMail>
</CONTACT>
</CONTACTS>
I have 4 XSl files which is working perfectly if I execute one by one using XSLT processor in Firefox XUL. When I execute all the XSL files one by one simultaneously it's not generating the final output.
This the actual output of the above XML file if I use the XSL files one by one:
<?xml version="1.0" encoding="UTF-8"?>
<CONTACTS>
<CONTACT>
<CUS-ID>PDE-ID2</CUS-ID>
<FirstName>Arun</FirstName>
<LastName>Arun_niit</LastName>
<gmail>[email protected]</gmail>
<yahoo>[email protected]</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
<CONTACT>
<CUS-ID>PDE-ID4</CUS-ID>
<FirstName>KumarVeera</FirstName>
<LastName>Veera Kumar</LastName>
<gmail/>
<yahoo>[email protected]</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>[email protected]</gmail>
<yahoo>[email protected]</yahoo>
<URL/>
<Facebook-ID/>
</CONTACT>
</CONTACTS>
This is the actual JS function to call the XSl file in XUL:
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();
}
These are the XSL files I'm using to generate my final output:
File1: To merge contacts with the same 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: To merge same email address of different contacts
<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>
File 3: File 3 to separate the email values according to domain type
<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>
File 4: Generate cutomer ID for each contact and add the email domain tag to the email values type from the 3rd xsl generated output file.
<?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>
Sometimes it's generating the proper output but most of the time it's not working.
I really don't understand what could be the problem. Is there any possibility to combine all these SL files as a single file? Please help me. Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要组合上面显示的转换,您需要一个
node-set()
扩展函数,您的 javascript 库可能无法提供该函数(是吗?)。但是,至少对于上面显示的输入示例(稍作更改以涵盖其他情况),我认为可以通过单个转换来执行所有任务。
请注意,当 URL 节点位于重复的 CONTACT 中时,您的解决方案(以及此解决方案)不会处理 Facebook-ID 生成的元素。
当应用于以下输入时:
产生:
To combine the transforms shown above you would need a
node-set()
extension function, which is probably not available from your javascript library (is it?).However, at least for the input sample shown above (slightly changed to cover other cases), I think it is possible to perform all of your tasks with a single transform.
Note your solution (and this one too) does not handle Facebook-ID generated element when URL node is in the duplicate CONTACT.
When applied on the following input:
produces: