0%

Vaults

A vault is a storage location residing in the underlying database that is defined by an ENOVIA Live Collaboration System Administrator for use by ENOVIA Live Collaboration. Vaults allow the designer of the ENOVIA Live Collaboration database to construct one or more logical storage locations within the database. The Business Administrator determines what the vault is for, while the System Administrator defines where the vault is located on the network. Vaults should use actual host and path names, not mounted directories. Paths must be exported on the host to all users
who require access to the vaults.

You must be a System Administrator to access vaults.

In addition to the business object vaults created by the System Administrator, a vault called the Administration vault that is created automatically when ENOVIA Live Collaboration is installed on your system. The Administration vault is used for administrative purposes only and serves as the master definition vault. The Administration vault is used for definitions only. You cannot use it for storing business objects. Vaults contain metadata (information about objects), while stores contain the application files associated with business objects. All vaults contain a complete set of ENOVIA Live Collaboration definitions. These definitions identify the characteristics of items such as persons, roles, types, formats, etc. When you make changes to a definition (such as add, modify, or delete), all definition copies must be updated to reflect the change. This update of the vaults occurs simultaneously if all the copies are available. If any of the copies are not available (a vault is not available), you cannot alter the definitions. This prevents partial alteration of the ENOVIA Live Collaboration definitions. For example, assume you want to add a new format definition. After you enter the Add Format command, ENOVIA Live Collaboration will attempt to add the definition. If the definition is valid (no errors), all copies of the ENOVIA Live Collaboration definitions are changed to include this new format. But assume that a vault resides on a host that is currently offline. In this case, no changes to the definitions are made. If changes were allowed, the one vault would not be updated to contain the change. Therefore, you should ensure that all defined vaults are available before modifying the ENOVIA Live Collaboration definitions.

Types of Vaults

There are four types of vaults:

  1. local
  2. remote
  3. foreign
  4. external.
  • Most vaults are local.
  • Remote vaults are used for loosely-coupled databases, which allow two entirely different ENOVIA Live Collaboration installations to share data.
  • Foreign vaults are used with Adaplets, which allow data from virtually any source to be modeled as ENOVIA Live Collaboration objects.
  • External (Web Service Adaplet) vaults are used with External stores that contain data maintained by external servers.

When defining a vault in MQL, you don’t need to specify which type it is. The system knows which type of vault you are defining by the parameters you specify for the vault.

  • For local vaults, you define Oracle tablespaces using the Tablespace and Indexspace clauses.
  • For remote vaults, you specify the server using the Server clause.
  • For foreign vaults, you specify tablespaces, and Interface and Map fields (using the Interface and Map clauses).
  • External vaults need only a parameters file.

Defining a Vault

Use the Add Vault command to define a vault:

add vault NAME [ADD_ITEM {ADD_ITEM}];

NAME is the name of the vault you are creating.
ADD_ITEM is an Add Vault clause that provides more information about the vault you are creating.

Printing a vault definition

print vault NAME;

If the NAME contains embedded spaces, use quotation marks

Delete Vault

delete vault NAME;

Clear Vault

The Clear Vault command is used to delete all business objects and associations in a vault:

clear vault NAME [minorrevision] [relationship] [full] [size NUMBER];

NAME is the name of the vault you want to clear.
NUMBER is the size of the transaction before a database commit. The Size clause only applies when any of the other optional clauses are included.

Once a Vault has been established and used, you should NOT use the Clear Vault command. In addition, you should not use it when users are online.

  • Minorrevision Clause

    Include this clause before actually clearing the vault to have first remove the business objects in the named vault from revision chains of objects in other vaults. This involves modifying rows in the vaults lxBO table (marking rows that need to be cleaned up). Upon successful execution of this command, all revision chains that need adjustment prior to the clear vault command are fixed.

  • Relation Clause

    Include this clause before actually clearing the vault to have ENOVIA Live Collaboration first disconnect business objects in the named vault from objects in other vaults. This involves modifying rows in the vaults lxRO table (marking rows that need to be cleaned up). Upon successful execution of this command, all connections to objects in other vaults are removed.

  • Full Clause

    Include this clause before actually clearing the vault to have ENOVIA Live Collaboration first perform both a “clear vault relationship” and a “clear vault revision.” Additionally all tables of the vault are dropped and recreated, cleaning up the marked rows.

  • Size Clause

    Include this clause of the clear vault command to indicate a transaction size before the relation or revision changes are committed to the database. For example, to remove all connections to or from objects in other vaults and commit the changes 100 at a time use the following:.

    clear vault MyVault relation size 100;

When used without the Revision, Relation or Full clauses, the Size clause is ignored.

Index Vault

The index command should be used periodically after modification and deletions to clean up the database indices.

index vault NAME [table TABLE_NAME [indexspace TABLESPACE_NAME]];

NAME is the name of the vault to index. You can run the index vault command against any vault, including ADMINISTRATION.

Re-indexing vaults can improve find performance whether or not transaction boundaries have been used in the data loading process. If data is loaded from a sequentially sorted data file, the resulting index will be less than optimal. Re-indexing randomizes the index, making find performance noticeably better. Indexing a vault in this manner rebuilds the system indices that must be present for locating objects by name, type, and owner, as well as other SQL convertible fields.

To show the SQL commands for a particular index vault command, without actually changing the indices, use the validate index vault command as follows:.

validate index vault NAME [table TABLE_NAME [indexspace TABLESPACE_NAME]];

This is helpful to use on very large databases, where indexing a vault may take many hours. The validate output shows the SQL commands that need to be run. You could then manually run the commands in order, to make progress with minimal disruption.

Each clause is described below.

  • Table Clause

Include this clause to indicate which database tables should be re-indexed. Only those columns that have indexing defined will be re-indexed. You should include up to and including the “_” in a table name, since what follows is specific to the vault specified. For example:

index vault "Engineering-1" table lxbo_;

This command might generate and execute SQL similar to:

alter index lxBO_abbe6b7a_lxOid_Index rebuild;
alter index lxBO_abbe6b7a_lxName_Index rebuild;
alter index lxBO_abbe6b7a_lxOwner_Index rebuild;
alter index lxBO_abbe6b7a_lxPolicy_Index rebuild;

The Engineering-1 vault is associated with the abbe6b7a table.

  • Indexspace Clause

Use this clause to specify an alternate database tablespace to use for processing this command. For example:

index vault “Engineering-1” table lxbo_ indexspace USER_DATA;

This SQL generated is as follows:

alter index lxBO_abbe6b7a_lxOid_Index rebuild tablespace USER_DATA;
alter index lxBO_abbe6b7a_lxName_Index rebuild tablespace USER_DATA;
alter index lxBO_abbe6b7a_lxOwner_Index rebuild tablespace USER_DATA;
alter index lxBO_abbe6b7a_lxPolicy_Index rebuild tablespace USER_DATA;
alter index lxBO_abbe6b7a_lxState_Index rebuild tablespace USER_DATA;

This command adds indices to all columns of lxBO_ table (of the vault Engineering-1) that have indexing defined, and the command would use tablespace USER_DATA to hold the index data.

You must also include the table clause with using the indexspace clause.

Fixing Fragmented Vaults

As objects are deleted from a vault, storage gaps will occur in the vault database file. These gaps represent wasted disk space and can cause an increase in access time. MQL provides the tidy vault command to fix fragmentations in the database file of the vault.

tidy vault NAME [commit N];
  • NAME is the name of the vault you want to fix. You can specify the ADMINISTRATION vault to remove unused records of deleted administration objects.

  • When this command is executed, ENOVIA Live Collaboration consolidates the fragmented database file. It deletes rows in the database tables that are marked for deletion.

  • Commit N Clause
    Include this clause when tidying large vaults. The number N that follows specifies that the command should commit the database transaction after this many objects have been tidied. The default is 1000. For example:

    tidy vault “Engineering” commit 200

The Commit N clause cannot be used for the ADMINISTRATION vault.

List of Vaults

A vault is a grouping of objects that depends on the types of objects used, the relationships they have to one another, and the people who need access to them.
The following code demonstrates how to get a list of vaults.

try{
     getContext().connect();
     VaultList list = Vault.getVaults(getContext());
     _context.disconnect();
     VaultItr itr = new VaultItr(list);
     while(itr.next())
     {
         Vault vault = itr.obj();
         System.out.println("vault: " + vault.getName());
     }
     getContext().disconnect();
}catch (MatrixException e){
 // Can’t load vaults
}

JPO in Enovia

Access to JPOs through the Studio Customization Toolkit consists of two invoke methods on a new JPO class.

  1. One form of the invoke method returns an int (useful for returning exit codes).)

    int ret = JPO.invoke(Context context, String className, String[] initargs, String methodName, String[] methodargs);

  2. The other form returns a Java Object.

    Object ret = JPO.invoke(Context context, String className, String[] initargs,String methodName,String[] methodargs, java.lang.Class retType);

An example of an object method in the “emxProject” JPO would be:

import matrix.db.*;
public class ${CLASSNAME} {
     public ${CLASSNAME} (Context context, String []args) {
    }
    public BusinessObjectList query(Context context, String []args) 
    {
        Query query = new Query(args[0]);
         return query.evaluate(context);
     }
}

called by the following in a .jsp:

String[] init = new String[] {};
String[] args = new String[] { ".finder" };
BusinessObjectList list = (BusinessObjectList)JPO.invoke(context, "Project", init, "query", args, BusinessObjectList.class);

Note the use of casting, which is necessary because the system only knows to return an
object instance. In the example above you see that BusinessObjectList is consistently used
for declaring the object to hold the return object, for casting, and for the sixth argument
that defines the return type.

The JPO class has two methods that correspond to serializing an Object into a String, and de-serializing a String back into an Object. The method names are packArgs and unpackArgs, respectively. Since JPOs only accept
strings as arguments
, you must use the packArgs/unpackArgs methods to convert Java objects to/from strings when using JPOs.

These methods actually work with a String array of size two, that holds the class in the first slot and the serialized object in the second slot. This allows users of the String array to do proper type casting.
One can build up several Objects in a String array by calling packArgs() several times using the proper indexing into the String array. However, it is better to place all arguments in a single compound object (like a hashmap) and then pack just the single compound object into the args array. Keep in mind that any Object needing to be passed as an argument in this way must implement the java.io.Serializable interface.You can only call packargs on objects that are serialized. In releases before 9.5.3.0, many of the Studio Customization Toolkit classes were not. Most classes are now serialized and so may be passed as arguments to JPOs.

The packArgs method has the following signature:

public static String[] packArgs(Object in) throws Exception

The unpackArgs method has the following signature:

public static Object unpackArgs(String[] in) throws Exception

The following packing logic is placed in a bean that is called from a JSP.

 /**
 * Sends an icon mail message to the specified users.
 *
 * @param context the Matrix <code>Context</code> object
 * @param toList the to list of users to notify
 * @param ccList the cc list of users to notify
 * @param bccList the bcc list of users to notify
 * @param subject the notification subject
 * @param message the notification message
 * @param objectIdList the list of objects to send with the 
notification
 * @throws FrameworkException if the operation fails
 * @since AEF 9.5.0.0
 * @grade 0
 */
 public static void sendMessage(Context context, StringList toList, StringList ccList, StringList bccList,     String subject, String message, StringList objectIdList) throws FrameworkException
     {
         try
         {
             ContextUtil.pushContext(context);
             // Create the arguments for the notification.
             Map note = new HashMap();
             note.put("toList", toList);
             note.put("ccList", ccList);
             note.put("bccList", bccList);
             note.put("subject", subject);
             note.put("message", message);
             note.put("objectIdList", objectIdList);
             // Pack arguments into string array.
             String[] args = JPO.packArgs(note);
             // Call the jpo to send the message.
             JPO.invoke(context, "emxMailUtil", null, 
            "sendMessage", args);
         }
         catch (Exception e)
         {
             throw (new FrameworkException(e));
         }
         finally
         {
             ContextUtil.popContext(context);
         }
 }

The unpacking logic is then found in the JPO method where it is performed prior to passing the arguments on to the worker method (this design pattern is very useful for hiding the details of packing and unpacking arguments).

 /**
 * Sends an icon mail notification to the specified users.
 *
 * @param context the Matrix <code>Context</code> object
 * @param args contains a Map with the following entries:
 * toList - the list of users to notify
 * ccList - the list of users to cc
 * bccList - the list of users to bcc
 * subject - the notification subject
 * message - the notification message
 * objectIdList - the ids of objects to send with the 
notification
 * @returns nothing
 * @throws Exception if the operation fails
 * @since AEF 9.5.0.0
 */
 public static int sendMessage(Context context, String[] args) throws Exception{
     if (args == null || args.length < 1)
     {
         throw (new IllegalArgumentException());
     }
     Map map = (Map) JPO.unpackArgs(args);
     sendMessage(context,(StringList) map.get("toList"), (StringList) map.get("ccList"), (StringList) map.get("bccList"), (String) map.get("subject"), (String) map.get("message"), (StringList) map.get("objectIdList"));
     return 0;
 }

Avoid getting business object selectable items one at a time. Code similar to the following should never exist:

///////////////////////////////////////////////////////////////
// Do not have code like below 
///////////////////////////////////////////////////////////////
// Query using MQLCommand
 MQLCommand mqlCmd = new MQLCommand();
 mqlCmd.executeCommand(ctx, "temp query bus t2 t2* 0 dump \n");
 String rslt = mqlCmd.getResult().trim();
 StringTokenizer st1 = new StringTokenizer(rslt,"\n");
 while (st1.hasMoreElements()) {
     String resultBo = st1.nextToken().trim();
     System.out.println("Result bo ="+resultBo);
     MQLCommand subMqlCmd = new MQLCommand();
     String mqlStr = "print bus "+resultBo+ " select attribute[int-u] attribute[color-u];";
     subMqlCmd.executeCommand(ctx, mqlStr);
     String subResult = subMqlCmd.getResult().trim();
     System.out.println("Sub result ="+subResult);
 }

Instead, multiple selectables should be specified in one command. Multiple selectable items can be specified for any of the following commands:

• print bus
• expand bus
• temp query
• print set

For example:

 MQLCommand mqlCmd = new MQLCommand();
 mqlCmd.executeCommand(ctx, "temp query bus t2 t2* 0 select attribute[int-u].value attribute[color-u].value    from[r3].attribute[rstring-u].value dump |");
 String result = mqlCmd.getResult().trim();
 StringTokenizer st = new StringTokenizer(result,"|");
 while (st.hasMoreTokens()) {
     System.out.println("Result token ="+st.nextToken());
 }

The coding approach shown above could be made more efficient by using the following syntax:

 // Query using ADK calls
 StringList busSelect = new StringList(7);
 busSelect.addElement("id");
 busSelect.addElement("type");
 busSelect.addElement("name");
 busSelect.addElement("revision");
 busSelect.addElement("attribute[int-u].value");
 busSelect.addElement("attribute[color-u].value");     
 busSelect.addElement("from[r3].attribute[rstring-u].value");

 // Prepare temp query
 Query query = new Query();
 query.setBusinessObjectType("t2");
 query.setBusinessObjectName("t2*");
 query.setBusinessObjectRevision("0");
 query.setOwnerPattern("*");
 query.setVaultPattern("unit1");
 query.setWhereExpression("");
 BusinessObjectWithSelectList bwsList = new BusinessObjectWithSelectList();
 
 // Do the query
 bwsList = query.selectTmp(ctx, busSelect); 
 // Iterate through the objects returned and get data.
 for (int idx=0; idx<bwsList.size(); idx++)
 {
     BusinessObjectWithSelect bws = (BusinessObjectWithSelect) bwsList.elementAt(idx);
     String sType = (String)bws.getSelectData("type"); 
     System.out.println("Type ="+sType);
     String sName = (String)bws.getSelectData("name"); 
     System.out.println("Name ="+sName);
     String sRevision = (String)bws.getSelectData("revision"); 
     System.out.println("Revision ="+sRevision);

     // Get businessobject attribute values
     String attrOneVal = (String)bws.getSelectData("attribute[int-u].value"); 
     System.out.println("AttrOneVal ="+attrOneVal);
     String attrTwoVal = (String)bws.getSelectData("attribute[color-u].value");
     System.out.println("AttrTwoVal ="+attrTwoVal);

     // Get relationship attribute values
     String attrRelVal = (String)bws.getSelectData("from[r3].attribute[rstring-u].value");
     System.out.println("AttrRelVal ="+attrRelVal);         
 } 

When an MQL selectable item is used to retrieve information about a relationship, the “relationship” item should not be used if a direction is known. Instead, “to” or “from” should be used. This reduces the number of database tables that need to be searched. For example, instead of:

relationship\[BOM\].attribute\[Qty\]

Use:

from\[BOM\].attribute\[Qty\]

what is MQL

MQL is the Matrix Query Language. Similar to SQL, MQL consists of a set of commands that help
the administrator set up and test an ENOVIA Live Collaboration database quickly and efficiently.
MQL is primarily a tool for building the ENOVIA Live Collaboration database. Also, you can use
MQL to add information to the existing database, and extract information from the database.

Filter History Data in Enovia v2013xE

                Map hmaplist = UINavigatorUtil.getHistoryData(this.ctx, objId);
                Vector timeArray = (Vector) hmaplist.get("time");
                Vector userArray = (Vector) hmaplist.get("user");
                Vector actionArray = (Vector) hmaplist.get("action");
                Vector stateArray = (Vector) hmaplist.get("state");
                Vector descriptionArray = (Vector) hmaplist.get("description");
                sb.append("\n" + objId + "~" + type + "~" + name + "~Current state = " + current + "~Branch To = " + strBranchTo);
                //System.out.println("\n" + objId + "~" + type + "~" + name + "~Current state = " + current + "~Branch To = " + strBranchTo);
                for (int i = 0; i < descriptionArray.size(); i++) {
                    String history = "history = ";
                    String desc = (String) descriptionArray.get(i);
                    if (desc.contains("Branch To")) {
                        String user = (String) userArray.get(i);
                        if (!user.split("\\:")[1].trim().equalsIgnoreCase("User Agent")) {
                            history += actionArray.get(i) + " ";
                            history += desc + " ";
                            history += userArray.get(i) + " ";
                            history += stateArray.get(i) + " ";
                            history += timeArray.get(i) + " ";
                            sb.append("\n\t" + history);
                        }
                    }
                }

Class RelationshipUtil

com.matrixone.apps.common.util.RelationshipUtil
public class RelationshipUtil extends java.lang.Object

The RelationshipUtil class provides tools to float objects.

Method Summary

access Method Name Description
static void connected(matrix.db.Context context, java.lang.Object objectId,java.lang.String relPattern, java.lang.String typePattern, java.lang.String expandDir, java.util.Map policyStateMap) Floats the specified relationships to this object.
static void connected(matrix.db.Context context, java.lang.Object objectId, java.lang.String relPattern, java.lang.String typePattern, java.lang.String expandDir, java.lang.String floatExpression) Floats the specified relationships to this object.

Method Detail

connected

1
2
3
4
5
6
7
public static void connected(matrix.db.Context context,
java.lang.Object objectId,
java.lang.String relPattern,
java.lang.String typePattern,
java.lang.String expandDir,
java.util.Map policyStateMap)
throws java.lang.Exception

Floats the specified relationships to this object. The objects connected to the previous revision of the given object and that meet the specified criteria are disconnected from the previous revision and connected to the given object. To meet the specified criteria, the objects must be connected to the previous revision of the given object through the relationship and type patterns, in the specified direction, and must be editable. To be editable, the object’s state must be one of the states listed in the policy-state map, or the object must not be in it’s last state.

Example:

1
2
3
4
5
6
7
BusinessObject mc = new BusinessObject("Microcomputer", "Q Prom",
"A", "Manufacturing");
HashMap sTargetState = new HashMap();
sTargetState.put("Production", "Active");
sTargetState.put("Documentation", "Finished");
HashMap returnedMsg = RelationshipUtil.connected(context, mc,
"", "", sTargetState, 0, "from", true);

Parameters:

  1. context - The matrix context object.
  2. objectId - The object to float relationships to.
  3. relPattern - The relationships to expand.
  4. expandDir - The direction to expand. This can be “from” or “to”. Anything else will expand in both directions.
  5. policyStateMap - A map from policy names to a list of the editable states in that policy.
    Throws:
    java.lang.Exception - if float failed.

connected

1
2
3
4
5
6
7
public static void connected(matrix.db.Context context,
java.lang.Object objectId,
java.lang.String relPattern,
java.lang.String typePattern,
java.lang.String expandDir,
java.lang.String floatExpression)
throws java.lang.Exception

Class com.matrixone.apps.common.util.ListUtil

public class ListUtil extends java.lang.Object

static method compareLists

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void compareLists(java.util.List oldList,
java.util.List newList,
java.util.List addedItems,
java.util.List removedItems,
java.util.List retainedItems)
Compare two lists and determine the added, removed, and retained items.
Parameters:
oldList - the old list to compare
newList - the new list to compare
addedItems - items that are only in the new list
removedItems - items that are only in the old list
retainedItems - items that are in both lists
Since:
AEF 9.5.1.0

For Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StringList list3 = new StringList();
list3.add("1");
list3.add("11");
list3.add("1111");
list3.add("11111");

StringList list4 = new StringList();
list4.add("11");
list4.add("21");
list4.add("111");
list4.add("211");
list4.add("311");

StringList added = new StringList();
StringList removed = new StringList();
StringList retained = new StringList();
ListUtil.compareLists(list3, list4, added, removed, retained);
System.out.println("list 3: " + list3);
System.out.println("list 4: " + list4);
System.out.println("list added: " + added);
System.out.println("list removed: " + removed);
System.out.println("list retained: " + retained);

Output:

list 3: [1, 11, 1111, 11111]
list 4: [11, 21, 111, 211, 311]
list added: [21, 111, 211, 311]
list removed: [1, 1111, 11111]
list retained: [11]

Get Attribute Default Value

AttributeType

1
2
AttributeType attrType = new AttributeType(attrName);
String defaultValue = attrType.getDefaultValue(context);

AttributeUtil

1
String strDefaultValue = AttributeUtil.getDefaultAttributeValue(context, attrName);

XML Sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<WebSites>
<Site>
<name>EPLM R2017 Docs</name>
<url>/B418doc/index.htm</url>
<category>Docs</category>
</Site>
<Site>
<name>EPLM R2013 Docs</name>
<url>/B214doc/DShomepage_English.htm</url>
<category>Docs</category>
</Site>
<Site>
<name>MyBlog</name>
<url>https://blog.ddong.online</url>
</Site>
<Site>
<name>JAVA 8 Docs</name>
<url>https://docs.oracle.com/javase/8/docs/api/overview-summary.html</url>
<category>Docs</category>
</Site>
</WebSites>

XSL Sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My Web Sites Collection - DT</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Site</th>
<th>URL</th>
<th>Description</th>
</tr>
<xsl:for-each select="WebSites/Site">
<xsl:sort select="category"/>
<tr>
<xsl:choose>
<xsl:when test="category = 'EPLM'">
<td bgcolor="grey">
<xsl:value-of select="name"/>
</td>
<td>
<a href="{url}" rel="noopener noreferrer" target="_blank">
<xsl:value-of select="url"/>
</a>
</td>
<td bgcolor="grey">
<xsl:value-of select="category"/>
</td>
</xsl:when>
<xsl:when test="category = 'ALPIM'">
<td bgcolor="yellow">
<xsl:value-of select="name"/>
</td>
<td>
<a href="{url}" rel="noopener noreferrer" target="_blank">
<xsl:value-of select="url"/>
</a>
</td>
<td bgcolor="yellow">
<xsl:value-of select="category"/>
</td>
</xsl:when>
<xsl:when test="category = 'AFP'">
<td bgcolor="red">
<xsl:value-of select="name"/>
</td>
<td>
<a href="{url}" rel="noopener noreferrer" target="_blank">
<xsl:value-of select="url"/>
</a>
</td>
<td bgcolor="red">
<xsl:value-of select="category"/>
</td>
</xsl:when>
<xsl:when test="category = 'Docs'">
<td bgcolor="green">
<xsl:value-of select="name"/>
</td>
<td>
<a href="{url}" rel="noopener noreferrer" target="_blank">
<xsl:value-of select="url"/>
</a>
</td>
<td bgcolor="green">
<xsl:value-of select="category"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<a href="{url}" rel="noopener noreferrer" target="_blank">
<xsl:value-of select="url"/>
</a>
</td>
<td>
<xsl:value-of select="category"/>
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Html & JavaScript combine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html>
<head>
<script>
function loadXMLDoc(filename){
if (window.ActiveXObject){
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}else{
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
return xhttp.responseXML;
}

function displayResult(){
xml = loadXMLDoc("mywebsites.xml");
xsl = loadXMLDoc("mywebsites.xsl");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document"){
ex = xml.transformNode(xsl);
document.getElementById("example").innerHTML = ex;
}else if (document.implementation && document.implementation.createDocument){
// code for Chrome, Firefox, Opera, etc.
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("example").appendChild(resultDocument);
}
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>

验证数字的正则表达式集

验证数字:

1
^[0-9]*$ 

验证n位的数字:

1
^\d{n}$ 

验证至少n位数字:

1
^\d{n,}$ 

验证m-n位的数字:

1
^\d{m,n}$ 

验证零和非零开头的数字:

1
^(0|[1-9][0-9]*)$ 

验证有两位小数的正实数:

1
^[0-9]+(.[0-9]{2})?$ 

验证有1-3位小数的正实数:

1
^[0-9]+(.[0-9]{1,3})?$ 

验证非零的正整数:

1
^\+?[1-9][0-9]*$ 

验证非零的负整数:

1
^\-[1-9][0-9]*$ 

验证非负整数(正整数 + 0)

1
^\d+$ 

验证非正整数(负整数 + 0)

1
^((-\d+)|(0+))$ 

验证长度为3的字符:

1
^.{3}$ 

验证由26个英文字母组成的字符串:

1
^[A-Za-z]+$ 

验证由26个大写英文字母组成的字符串:

1
^[A-Z]+$ 

验证由26个小写英文字母组成的字符串:

1
^[a-z]+$ 

验证由数字和26个英文字母组成的字符串:

1
^[A-Za-z0-9]+$ 

验证由数字、26个英文字母或者下划线组成的字符串:

1
^\w+$ 

验证用户密码:

1
^[a-zA-Z]\w{5,17}$ 

正确格式为:以字母开头,长度在6-18之间,只能包含字符、数字和下划线。

验证是否含有 ^%&’,;=?$" 等字符:

1
[^%&',;=?$\x22]+ 

验证汉字:

1
^[\u4e00-\u9fa5],{0,}$ 

验证Email地址:

1
^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$

验证InternetURL:

1
^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ ;^[a-zA-z]+://(w+(-w+)*)(.(w+(-w+)*))*(?S*)?$ 

验证电话号码:

1
^(\d3,4|\d{3,4}-)?\d{7,8}$

–正确格式为:XXXX-XXXXXXX,XXXX-XXXXXXXX,XXX-XXXXXXX,XXX-XXXXXXXX,XXXXXXX,XXXXXXXX。
验证身份证号(15位或18位数字):

1
^\d{15}|\d{}18$ 

验证一年的12个月:

1
^(0?[1-9]|1[0-2])$

正确格式为:“01”-“09”和“1”“12”
验证一个月的31天:

1
^((0?[1-9])|((1|2)[0-9])|30|31)$

正确格式为:01、09和1、31。
整数:

1
^-?\d+$ 

非负浮点数(正浮点数 + 0):

1
^\d+(\.\d+)?$ 

正浮点数

1
^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 

非正浮点数(负浮点数 + 0)

1
^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 

负浮点数

1
^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ 

浮点数

1
^(-?\d+)(\.\d+)?$

Using Control Characters

All editing commands are control characters which are entered by holding the Ctrl or Esc key while typing another key, as listed in the following table. All editing commands operate from any place on the line, not just at the beginning of the line.

Command Line Editing Control Characters

Control Character Description
Ctrl-A Moves the cursor to the beginning of the line.
Ctrl-B Moves the cursor to the left (back) one column.
Esc-B Moves the cursor back one word.
Ctrl-D Deletes the character to the right of the cursor.
Ctrl-E Moves the cursor to the end of the line.
Ctrl-F Moves the cursor right (forward) one column.
Esc-F Moves the cursor forward one word.
Ctrl-H Deletes the character to the left of the cursor.
Ctrl-I Jumps to the next tab stop.
Ctrl-J Returns the current line.
Ctrl-K Kills from the cursor to the end of the line (see Ctrl-Y).
Ctrl-L Redisplays the current line.
Ctrl-M Returns the current line.
Ctrl-N Fetches the next line from the history list.
Ctrl-O Toggles the overwrite/insert mode, initially in insert mode.
Ctrl-P Fetches the previous line from the history list.
Ctrl-R Begins a reverse incremental search through the history list. Each printing character typed adds to the search substring (which is empty initially). MQL finds and displays the first matching location. Typing Ctrl-R again marks the current starting location and begins a new search for the current substring.
Type Ctrl-H Or press the Del key to delete the last character from the search string. MQL restarts the search from the last starting location.Repeated Ctrl-H or Del characters, therefore, unwind the search to the match nearest to the point where you last typed Ctrl-R or Ctrl-S (described below).Type Esc or any other editing character to accept the current match and terminate the search.
Type Ctrl-H Or press the Del key until the search string is empty to reset the start of the search to the beginning of the history list. Type Esc or any other editing character to accept the current match and terminate the search.
Ctrl-S Begins a forward incremental search through the history list. The behavior is like Ctrl-R but in the opposite direction through the history list.
Ctrl-T Transposes the current and previous character.
Ctrl-U Kills the entire line (see Ctrl-Y).
Ctrl-Y Yanks the previously killed text back at the current location.Backspace Deletes the character left of the cursor.
Del Deletes the character right of the cursor.
Return Returns the current line.
Tab Jumps to the next tab stop.