开发者

Generating two different outputs for the same XSL file?

开发者 https://www.devze.com 2023-03-21 12:46 出处:网络
This is my XML file and If i run the XSLt file i\'ll get the same output in the same order exactly in Eclipse XSL Transformation.

This is my XML file and If i run the XSLt file i'll get the same output in the same order exactly in Eclipse XSL Transformation. Even if add a new record to my xml file and run the XSL file, the <xsl:value-of select="generate-id(.)"/> will create unique id for the new record.

<?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>

This is my updated XSLT file:

  <?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>

Then I used the same XSLT file for XSLT processor function in XUL, which I'm getting a different type of ID and output. It's keep generating a new ID for old record and for new record If i add a new record in XML file.

How do i generate a new id only for the new record? and how can i have the same XML template of my input file to my XML output file.

This is the output i'm getting:

<?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><Cu开发者_StackOverflow社区stomer-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>

This is my Javascript to call the XSLT file: The script call this function after saving the XML file. The new record will update in the same as mentioned in the input xml file.

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");

} 

Thank you very much.


If generate-id() produces repeatable results in different runs, then that's an accident of the design of your XSLT processor, not a behaviour you can rely on.


I don't know what XSLT processor Eclipse uses. At least with some extensions, you can configure the processor, e.g. to Xalan or Saxon. Mozilla/XUL uses Transformiix, at least by default. I read somewhere that it could be made to use Saxon. There are certainly differences between different XSLT processors.

The specification for generate-id() does not say what the generated ids should look like; only that they "must consist of ASCII alphanumeric characters and must start with an alphabetic character".

If you want XSLT-under-XUL to produce the same kinds of IDs as under Eclipse, you have a couple of options.

1) You could try and get XUL to use the XSLT processor that Eclipse uses. I don't know if this is possible.

2) Implement your own custom template for generating IDs.

With the latter, it would not be hard to imitate the style of the IDs you get in Eclipse, and to make them stable across multiple runs and different XSLT processors, if you have some stable data to base them on.

For example, if the order of your records is always stable (old records will never be deleted, or swapped, or replaced), then you could use a template like this to generate IDs:

<xsl:template match="node()" mode="generate-id">
    <xsl:text>N</xsl:text>
    <xsl:number level="any" count="node()" format="00001"/>        
</xsl:template>

If the order is not stable, but the first name + last name is both stable and unique, you could use

<xsl:template match="node()" mode="generate-id">
   <xsl:value-of select="concat(FirstName, LastName)" />
</xsl:template>


generate-id() works that way, you could verify if there are a Customer-ID in the Contact before you use the generate-id() I think...

<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>
0

精彩评论

暂无评论...
验证码 换一张
取 消