Tutorial of LBXML Operator, a C# API-Based Tool for XML Insertion, Modification, Searching, and Remo

1. Configurations for LBXML Operator

LBXML Operator runs over the .NET platform. 2.0, the latest version of LBXML Operator, has been tested successfully over the .NET 2003 platform.

It is easy to install LBXML Operator. Two DLLs, as follow, are what you need to care about. To install it, what you need to do is to make just two references in your C# applications for the two DLLs.

com.lblabs.tools.csharp.dll
com.lblabs.xmltool.dll

To program with LBXML Operator, declare the following statements at the beginning of your C# code:

using com.lblabs.xmltool.csharp;
using com.lblabs.xmltool;

It is noted that LBXML Operator is just developed in an initial phase. In the further versions, more types of operations will be designed to support more powerful functionalities.

Another issue is that LBXML Operator is not responsible for validating the XML file. So, when using any APIs in LBXML Operator, users need to make sure that the XML file must be validated after the particular operation, such as modification, insertion, and removal. Otherwise, the XML parser may interrupt the system execution.

2. Examples of Using LBXML Operator

The operations on XML are categorized into four types: insertion, modification, searching, and removal. This section discusses the four types of operation one by one. All the operations are included in the CSharpLBXMLOperator class.

To make a clear explanation, a typical XML file is selected and example of operations are shown on it. The XML and its DTD are listed as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
        <Vocabulary>
           <VocabularyName>OrderedNumber</VocabularyName>
           <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 1. The XML file used as an example in the article

<!ELEMENT RequirementInSAT (Version, NewSAT*, ExistingSAT*)>
<!ELEMENT Version (#PCDATA)>
<!ELEMENT NewSAT (SAT*)>
<!ELEMENT ExistingSAT (SAT*)>
<!ELEMENT SAT (Organization*, User*, Workflow*, Form*, Vocabulary*,
               Contract*)>
<!ELEMENT Organization (#PCDATA)>
<!ELEMENT User (#PCDATA)>
<!ELEMENT Workflow (#PCDATA)>
<!ELEMENT Form (Request, Response)>
<!ELEMENT Request (#PCDATA)>
<!ELEMENT Response (#PCDATA)>
<!ELEMENT Vocabulary (VocabularyName*)>
<!ELEMENT VocabularyName (#PCDATA)>
<!ELEMENT Contract (ContractName*)>
<!ELEMENT ContractName (#PCDATA)>

List 2. DTD for the XML file to be used as an example in the article

2.1 Insertion

The latest version of LBXML Operator provides two types of XML insertions. They are insertNodeByParentTag() and insertNodeByParentTagAndParentSibling().

2.1.1 insertNodeByParentTag()

When using this method to insert a tag and its value into an XML, you mudy specify the parent tag, the tag to be inserted and the value of the tag. The format of the method is defined as follows.

bool insertNodeByParentTag(String xmlFile, String parentTag,
                           String updateTag, String updateValue)

For example, if a tag, VocabularyName, and its value, CurrentCash, need to be inserted into the XML file of List 1, the code is listed as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.insertNodeByParentTag("./xmlfile.xml", "Vocabulary",
                                    "VocabularyName",
                                    "CurrentCash");

After the operation, the XML file of List 1 is changed. The new tag, VocabularyName, and its value, CurrentCash, are inserted below the Vocabulary tag. Because the Vocabulary tag appears two times in the XML file, the inserted tag, VocabularyName and its value, CurrentCash, also are inserted two times. The XML file after the operation is shown as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
            <VocabularyName>CurrentCash</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
            <VocabularyName>CurrentCash</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 3. The XML file after the operation, insertNodeByParentTag()

2.1.2 insertNodeByParentTagAndParentSibling()

It is possible that the tag, Vocabulary, and its value, CurrentCash, should be inserted only below the first tag, Vocabulary. Under this situation, the method is insertNodeByParentTagAndParentSibling(). The format is shown as follows.

bool insertNodeByParentTagAndParentSibling(String xmlFile,
     String parentTag, String parentSiblingTag,
     String parentSiblingValue, String updateTag,
     String updateValue)

The code to use the above method is shown as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.insertNodeByParentTagAndParentSibling("./xmlfile.xml",
              "Vocabulary", "Organization", "BigBug.com",
              "VocabularyName", "CurrentCash");

The difference between insertNodeByParentTagAndParentSibling() and insertNodeByParentTag() is that new parameters, parentSiblingTag and parentSiblingValue, are specified. Through the two parameters, the LBXML Operator is able to figure out the position to insert the new tag and its value. The following list shows in the new XML after the operation.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
            <VocabularyName>CurrentCash</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 4. The XML file after the operation, insertNodeByParentTagAndParentSibling()

Tutorial of LBXML Operator, a C# API-Based Tool for XML Insertion, Modification, Searching, and Remo

2.2 Removal

At present, the removal operation of LBXML Operator provides only one method, removeNodeByTagValue(). More powerful APIs will be implemented soon. The format of the method is shown as follows.

bool removeNodeByTagValue(String xmlFile, String tag, String value)

The operation is too simple. The tag and value parameters are similar to the key and key value for the same level XML tags. If you specify the tag and value parameters, all the same level tags and corresponding values are removed. For example, to remove the part between the NewSAT tag, the tag and value parameters of the method should be Organization and BigBug.com. The corresponding code is shown as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.removeNodeByTagValue("./xmlfile.xml", "Organization",
                                   "BigBug.com");

After the operation, the new XML is shown in List 5.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 5. The XML file after the operation, remove NodeByTagValue()

2.3 Modification

LBXML Operator provides powerful XML modification functionalities. Nine methods are designed to describe complex conditions in order to modify XML files.

2.3.1 changeByValue()

changeByValue() is a simple method to modify XML files by value. When specifying the oldValue and newValue parameters, the oldValue is changed to newValue. The format of changeByValue() is shown as follows.

bool changeByValue(String xmlFile, String oldValue, String newValue)

For example, to change the old value, CreditCheckingContract, to the new value, CreditContract, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByValue("./xmlfile.xml",
                            "CreditCheckingContract",
                            "CreditContract");

After the above operation, the new XML file is changed as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 6. The XML file after the operation, changeByValue()

2.3.2 changeByTag()

changeByTag() is also a simple method to modify XML. Because only a tag and corresponding new value are specified in the parameters, the values of all the tags appeared in an XML are changed after the operation. The format of the method is shown as follows.

bool changeByTag(String xmlFile, String tag, String newValue)

For example, if the value of the VocabularyName tag needs to be changed to null, the code can be written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByTag("./xmlfile.xml", "VocabularyName", "null");

After the operation, the XML file is changed as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>null</VocabularyName>
            <VocabularyName>null</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>null</VocabularyName>
            <VocabularyName>null</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 7. The XML file after the operation, changeByTag()

2.3.3 changeByTagNewValue()

Compared with changeByTag(), changeByTagNewValue() provides a new parameter, oldValue. Users specify the parameter to change the value of a tag. If so, only the value of the tag that is equal to the oldValue is changed. The format of the method is shown as follows.

bool changeByTagNewValue(String xmlFile, String tag,
                         String oldValue, String newValue)

For example, if users only want to change the value, CreditRequestNo, of the VocabularyName tag to CreditResponseNo, the code can be written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByTagNewValue("./xmlfile.xml", "VocabularyName",
                                  "CreditRequestNo",
                                  "CreditResponseNo");

After the operation, the new XML file is changed as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditResponseNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 8. The XML file after the operation, changeByTagNewValue()

2.3.4 changeByNoTagNewValue()

changeByNoTagNewValue() is similar to changeByTagNewValue(). The difference is that the value of a tag is specified by the sequential number of the tag in the XML file instead of by the old value of the tag. The format of the method is shown as follows.

bool changeByNoTagNewValue(String xmlFile, String tag, int no,
                           String newValue)

For example, if users want to do the same change as the example in the 3.3.3, i.e., the value, CreditRequestNo, of the VocabularyName tag to CreditResponseNo, the code can also be written as follows using changeByNoTagNewValue().

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByNoTagNewValue("./xmlfile.xml",
                                    "VocabularyName", 2,
                                    "CreditResponseNo");

Here, the sequential number of the VocabularyName tag is 2 (starting from 0) in the XML file. After the operation, the changed XML file is the same as the one in List 8.

2.3.5 changeBySiblingTagNewValue()

Although changeByTagNewValue() and changeByNoTagNewValue() provide the functionality to figure out which tag's value is to be changed, both of them have drawbacks. If more than one tag's values are equal to the specified old value, changeByTagNewValue() cannot differentiate which one should be changed so that all the tags' value that is equal to the old value is changed to the new value.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByTagNewValue("./xmlfile.xml", "ContractName",
                                  "CreditCheckingContract",
                                  "CreditContract");

For example, if the above code is executed, all the values of the ContractName tag, whose value is equal to CreditCheckingContract, are changed to CreditContract. The new XML file is shown in List 9.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 9. The XML file after the operation, changeByTagNewValue()

The drawback of the changeByNoTagNewValue() method is that sometimes it is hard to know the sequential number of a particular tag in an XML file, especially when the XML file is large.

changeBySiblingTagNewValue() overcomes the above drawbacks. By specifying the sibling tag of the tag whose value to be changed, LBXML Operator is able to figure out which tag's value should be changed exactly. The format of the method is as follows.

bool changeBySiblingTagNewValue(String xmlFile, String siblingTag,
                                String siblingValue, String newValue)

For example, users need to change the CreditCheckingContract value of the first tag, ContractName (there are two such tags in the XML file). In this case, the sibling tag is also ContractName, but its value is WholesaleContract. So, the code can be written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeBySiblingTagNewValue("./xmlfile.xml",
                                         "ContractName",
                                         "WholesaleContract",
                                         "CreditContract");

After the operation, the changed XML file is shown as follows. It is found that only the first ContractName, whose old value is CreditCheckingContract, is changed to CreditContract.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 10. The XML file after the changeBySiblingTagNewValue operation

Tutorial of LBXML Operator, a C# API-Based Tool for XML Insertion, Modification, Searching, and Remo

2.3.6 changeBySiblingTagUpdateTagNewValue()

Although changeBySiblingTagNewValue() overcomes some drawbacks of changeByTagNewValue() and changeByNoTagNewValue(), problems still exist in it. In general, changeBySiblingTagNewValue() demands by default that the tag whose value to be changed is the same as its sibling tag. For example, the section 2.3.3, the ContractName tag, whose CreditCheckingContract value needs to be changed, is specified by its sibling tag, another ContractName tag, just beyond it.

However, it is common to see that a tag is different from its sibling tag. For example, the sibling tag of the User tag in the XML file is Organization. In this case, changeBySiblingTagNewValue() does not work at all. In this situation, changeBySiblingTagUpdateTagNewValue() is able to do that instead of changeBySiblingTagNewValue() because the method does not require the tag whose value to be changed is the same as its sibling tag. The format of the tag is shown as follows.

bool changeBySiblingTagUpdateTagNewValue(String xmlFile,
     String siblingTag, String siblingValue, String updateTag
     String newValue)

For example, if users need to change the value of the User tag from customer to guest, the code can be written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeBySiblingTagUpdateTagNewValue("./xmlfile.xml",
    "Organization", "BigBug.com", "User", "Guest");

After the operation, the new XML file is shown as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 11. The XML file after the changeBySiblingTagUpdateTagNewValue() operation

2.3.7 changeByKeyTagKeyValueUpdateTagNewValue()

changeBySiblingTagNewValue() and changeBySiblingTagUpdateTagNewValue() provide modifications based on sibling tags. However, some tags must have no sibling tag. For example, the third ContractName tag, whose value is CreditCheckingContract, has no sibling tag. If the tag's value needs to be changed, only the changeByNoTagNewValue() method can be used. As mentioned before, usually it is hard to get the sequential number of the tag whose value to be changed especially, when the XML file is large. So, it is essential to have other approaches to deal with such problems.

changeByKeyTagKeyValueUpdateTagNewValue() modifies XML files based on key tags, not sibling tags. The format of the method is shown as follows.

bool changeByKeyTagKeyValueUpdateTagNewValue(String xmlFile,
     String keyTag, String keyValue, String updateTag,
     String newValue)

To change the value of the third ContractName in the XML file, the code can be written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByKeyTagKeyValueUpdateTagNewValue(
     "./xmlfile.xml", "Organization", "RequiredCreditChecking.com",
     "ContractName", "CreditContract");

The above code changes the value of the third ContractName from CreditCheckingContract to CreditContract. The method accesses the tag's value through its key tag, Organization, and its value, RequiredCreditChecking.com. After the operation, the changed XML file is shown as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditRequestNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 12. The XML file after the operation, changeByKeyTagKeyValueUpdateTagNewValue()

2.3.8 changeByKeyTagKeyValueSiblingTagUpdateTagNewValue()

Sometimes, it is necessary to modify a tag's value based on both of key tags and sibling tags. For example, users would like to modify the value, CreditRequestNo, of the VocabularyName tag. The changeByTagNewValue() method can be used to do that. For a small XML file, it must work correctly. However, if the XML file is large, this method is easy to impact other tags' value because it does not provide enough information to figure out which tag's value is to be changed.

changeBySiblingTagNewValue() does not work properly because there is another VocabularyName whose sibling tag's value is the same as the one to be changed. changeBySiblingTagUpdateTagNewValue() cannot deal with the case either. Although the method provides a new parameter to specify the tag to be changed, the sibling tag is the same as the tag to be changed in this case.

changeByKeyTagKeyValueUpdateTagNewValue() does not work either because there are two identical tags (VocabularyName) whose key tag (Organization) is also the same. If you use the method, both of the values of the two tags (VocabularyName) will be changed.

To handle this problem, a new method, changeByKeyTagKeyValueSiblingTagUpdateTagNewValue(), which combines the changeBySiblingTagUpdateTagNewValue() and changeByKeyTagKeyValueUpdateTagNewValue(), is designed. The format of the method is shown as follows.

bool changeByKeyTagKeyValueSiblingTagUpdateTagNewValue(
     String xmlFile, String keyTag, String keyValue,
     String siblingTag, String siblingValue, String updateTag,
     String newValue)

This method can deal with the above problem. For example, to change the value, CreditRequestNo, of the VocabularyName tag to CreditNo, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
lbXMLOperator.changeByKeyTagKeyValueSiblingTagUpdateTagNewValue(
     "./xmlfile.xml", "Organization", "RequiredCreditChecking.com",
     "VocabularyName", "OrderedNumber", "VocabularyName", "CreditNo");

After the operation, the changed XML file is shown as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Form>
            <Request>OrderForm</Request>
            <Response>ReceiptForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>InputCreditCardNumber</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>RequiredCreditChecking.com</Organization>
         <User>guest</User>
         <Workflow>Customer-Creditor</Workflow>
         <Form>
            <Request>CreditRequestForm</Request>
            <Response>CreditResponseForm</Response>
         </Form>
         <Vocabulary>
            <VocabularyName>OrderedNumber</VocabularyName>
            <VocabularyName>CreditNo</VocabularyName>
         </Vocabulary>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 13. The XML file after thechangeByKeyTagKeyValueSiblingTagUpdateTagNewValue() operation

2.3.9 changeByMultipleTagsAndWhere()

changeByMultipleTagsAndWhere() is the most powerful method to modify XML files. It is used to modify more complicated XML files than the ones mentioned above. For example, by using changeByKeyTagKeyValueSiblingTagUpdateTagNewValue(), only three-level XML files can be changed. The three levels are key tag, sibling tag, and update tag. Although in most cases it is not so difficult to figure out three levels to do modification even in a complicated XML file, it is better to design a method that supports no limited levels XML files modification. changeByMultipleTagsAndWhere() is the method to do that.

The format of changeByMultipleTagsAndWhere() is shown as follows.

bool changeByMultipleTagsAndWhere(String xmlFile,
     Hashtable keyTagHash, Hashtable keyValueHash)

For example, if users need to change the value, greatfree, of the UserName tag in the XML file of List 14, the code is designed as follows. All the above modification methods cannot be used here.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable keyTagHash             = new Hashtable();
xHashtable keyValueHash          = new Hashtable();
keyTagHash.put("0",   "OrganizationName");
keyTagHash.put("1",   "ExternalName");
keyTagHash.put("2",   "ExternalPropertyName");
keyTagHash.put("3",   "ExternalPropertyValue");
keyValueHash.put("0", "BigBug.com");
keyValueHash.put("1", "PC");
keyValueHash.put("2", "UserName");
keyValueHash.put("3", "plum");
lbXMLOperator.changeByMultipleTagsAndWhere("./xmlFile.xml",
     keyTagHash, keyValueHash);

After running the code, the XML is changed as shown in List 15.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd">
<RequirementInSAT>
   <SAT>
      <Organization>
         <OrganizationName>BigBug.com</OrganizationName>
         <External>
            <ExternalDetail>
               <ExternalName>PC</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>InStock</ExternalPropertyName>
                  <ExternalPropertyValue>9</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>MerchandisePrice</ExternalPropertyName>
                  <ExternalPropertyValue>399</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
            <ExternalDetail>
               <ExternalName>customer</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>UserName</ExternalPropertyName>
                  <ExternalPropertyValue>greatfree</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>Password</ExternalPropertyName>
                  <ExternalPropertyValue>111111</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>CreditCardNumber</ExternalPropertyName>
                  <ExternalPropertyValue>1234567890</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
         </External>
      </Organization>
      <Organization>
         <OrganizationName>SmallBug.com</OrganizationName>
         <External>
            <ExternalDetail>
               <ExternalName>PC</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>InStock</ExternalPropertyName>
                  <ExternalPropertyValue>9</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>MerchandisePrice</ExternalPropertyName>
                  <ExternalPropertyValue>399</ExternalPropertyValue>
               </ExternalProperty>
               </ExternalDetail>
            <ExternalDetail>
               <ExternalName>customer</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>UserName</ExternalPropertyName>
                  <ExternalPropertyValue>plum</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>Password</ExternalPropertyName>
                  <ExternalPropertyValue>111111</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>CreditCardNumber</ExternalPropertyName>
                  <ExternalPropertyValue>1234567890</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
         </External>
      </Organization>
   </SAT>
</RequirementInSAT>

List 14. A more complex XML file to show the example of the method, changeByMultipleTagsAndWhere()

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd">
<RequirementInSAT>
   <SAT>
      <Organization>
         <OrganizationName>BigBug.com</OrganizationName>
         <External>
            <ExternalDetail>
               <ExternalName>PC</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>InStock</ExternalPropertyName>
                  <ExternalPropertyValue>9</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>MerchandisePrice</ExternalPropertyName>
                  <ExternalPropertyValue>399</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
            <ExternalDetail>
               <ExternalName>customer</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>UserName</ExternalPropertyName>
                  <ExternalPropertyValue>plum</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>Password</ExternalPropertyName>
                  <ExternalPropertyValue>111111</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>CreditCardNumber</ExternalPropertyName>
                  <ExternalPropertyValue>1234567890</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
         </External>
      </Organization>
      <Organization>
         <OrganizationName>SmallBug.com</OrganizationName>
         <External>
            <ExternalDetail>
               <ExternalName>PC</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>InStock</ExternalPropertyName>
                  <ExternalPropertyValue>9</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>MerchandisePrice</ExternalPropertyName>
                  <ExternalPropertyValue>399</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
            <ExternalDetail>
               <ExternalName>customer</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>UserName</ExternalPropertyName>
                  <ExternalPropertyValue>plum</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>Password</ExternalPropertyName>
                  <ExternalPropertyValue>111111</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>CreditCardNumber</ExternalPropertyName>
                  <ExternalPropertyValue>1234567890</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
         </External>
      </Organization>
   </SAT>
</RequirementInSAT>

List 15. The XML file after the operation, changeByMultipleTagsAndWhere()

Tutorial of LBXML Operator, a C# API-Based Tool for XML Insertion, Modification, Searching, and Remo

2.4 Searching

LBXML Operator provides ten methods to search XML files. Similar to other methods in LBXML Operator, searching conditions are specified through method interfaces (APIs). Another feature is that searching results are returned into C# powerful data structures, such as String and Hashtable, which are convenient for further processing.

2.4.1 selectByKeyTag()

selectorByKeyTag() is utilized to search the value of the tag that is unique in an XML file. The format of the method is shown as follows.

String selectByKeyTag(String xmlFile, String keyTag)

For example, to search the value of the Version tag, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
String version = lbXMLOperator.selectByKeyTag("./xmlfile.xml",
                                              "Version");
Console.WriteLine("version = " + version);

After running the above code, the result is shown as follows.

version = 2.10
2.4.2 selectByTagAndWhere()

selectorByKeyTag() is not suitable to search the value of the tag that is not unique in an XML file. For example, to search the value of the User tag, it is a good idea to use selectByTagAndWhere() because User is not the unique tag in the XML file. The format of the method is shown as follows.

String selectByTagAndWhere(String xmlFile, String keyTag,
                           String searchTag, String keyValue)

To search the value of the User tag, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
String user = lbXMLOperator.selectByTagAndWhere("./xmlfile.xml",
              "Organization", "User", "BigBug.com");
Console.WriteLine("user = " + user);

After the above is executed, the following result is displayed. The User's value is customer.

user = customer
2.4.3 selectByBelowTagAndWhere()

In the parameters of the selectByTagAndWhere() method, the key tag is beyond the tag to be searched. Sometimes it is probable that the key tag is below the tag to be searched. The selectByBelowTagAndWhere() method is used to handle this problem. The format of the method is shown as follows.

String selectByBelowTagAndWhere(String xmlFile, String belowKeyTag,
                                String searchTag,
                                String belowKeyValue)

For example, if users need to search the value of the tag, Organization, the User tag can be used as a key tag. The code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
String organization = lbXMLOperator.selectByBelowTagAndWhere(
       "./xmlfile.xml", "User", "Organization", "customer");
Console.WriteLine("organization = " + organization);

The following result is displayed after the above code is executed.

organization = BigBug.com
2.4.4 selectHash()

It is always possible that a tag has multiple entries in an XML file and sometimes users would like to obtain all the values of a particular tag. In this case, the selectHash() method is suitable to retrieve all the values of a particular tag and store them into a C# Hashtable. The format of the method is shown as follows.

Hashtable selectHash(String xmlFile, String hashTag)

For example, to retrieve all the values of the VocabularyName tag in the XML file, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable vocabularyNameHash = new Hashtable();
vocabularyNameHash = lbXMLOperator.selectHash("./xmlfile.xml",
                                              "VocabularyName");
Console.WriteLine("vocabularyNameHash = " + vocabularyNameHash);

After running the above code, the following result is displayed.

vocabularyNameHash = {3=CreditRequestNo, 2=OrderedNumber,
                      1=InputCreditCardNUmber, 0=OrderedNumber}
2.4.5 selectSet()

Similar to the selectHash() method, the selectSet() method also deals with the problem to retrieve all the values of a particular tag in an XML file. The difference between them is that the result of selectSet() is stored into Hashtable in which the same value for different keys does not exist. The format of the method is shown as follows.

Hashtable selectSet(String xmlFile, String setTag)

For example, to do the same searching in Section 2.4.4, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable vocabularyNameSet = new Hashtable();
vocabularyNameSet = lbXMLOperator.selectSet("./xmlfile.xml",
                                            "VocabularyName");
Console.WriteLine("vocabularyNameSet = " + vocabularyNameSet);

After the above searching, the result is displayed as follows.

vocabularyNameSet = [OrderedNumber, InputCreditCardNumber,
                     CreditRequestNo]

It is noted that OrderedNumber appears two times in the result of selectHash(), but it has only one entry in the result of selectSet() because the result is stored in Hashtable instead of Hashtable.

2.4.6 selectByTagAndWhereForHash()

selectByTagAndWhereForHash() is the integration of the selectByKeyAndWhere() method and the selectHash() method. Because it is required to specify a key tag and its value in the parameters of the method, the number of searching results is smaller than that from selectHash(), i.e., only the values that are related to the key tag are returned into a Hashtable. The format of the method is shown as follows.

Hashtable selectByTagAndWhereForHash(String xmlFile, String keyTag,
                                     String searchTag,
                                     String keyValue)

For example, if users need to search values of the VocabularyName tag, which are related to the BigBug.com value, of the key tag, Organization, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable vocabularyNameHash = new Hashtable();
vocabularyNameHash = lbXMLOperator.selectByTagAndWhereForHash(
                     "./xmlfile.xml", "Organization",
                     "VocabularyName",
                     "BigBug.com");
Console.WriteLine("vocabularyNameHash = " + vocabularyNameHash);

The result of the above code is shown as follows.

vocabularyNameHash = {1=InputCreditCardNumber, 0=OrderedNumber}
2.4.7 selectByTagAndWhereForSet()

Similar to the selectByTagAndWhereForHash() method, selectByTagAndWhereForSet() has the same functionality. The difference is that the searching result is returned into a Hashtable for set instead of a Hashtable. The format of the method is shown as follows.

Hashtable selectByTagAndWhereForSet(String xmlFile, String keyTag,
                                    String searchTag,
                                    String keyValue)

If you are doing the same searching as the Section 2.4.6, the code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable vocabularyNameSet = new Hashtable();
vocabularyNameSet = lbXMLOperator.selectByTagAndWhereForSet(
   "./xmlfile.xml", "Organization", "VocabularyName", "BigBug.com");
   Console.WriteLine("vocabularyNameSet = " + vocabularyNameSet);

The result of the above code is displayed as follows.

vocabularyNameSet = [OrderedNumber, InputCreditCardNumber]
2.4.8 selectByMultipleTagsAndWhere()

selectByMultipleTagsAndWhere() is a powerful searching approach. By using this method, users can specify more complex conditions to retrieve a value of a tag than the ones in the above sections. The method is suitable to XML files that have a lot of levels. Usually, when the level of an XML exceeds four, it is possible to consider using the method. The format of the method is shown as follows.

String selectByMultipleTagsAndWhere(String xmlFile,
                                    Hashtable keyTagHash,
                                    Hashtable keyValueHash)

There are two Hashtables in the parameters of the method. The two Hashtables are used to store complex conditions to retrieve a value of a tag. The first one, keyTagHash, is used to store key tags and the second, keyValueHash, is used to store corresponding key values. With those constraints, the method is able to retrieve the value of a particular tag exactly.

To demonstrate the utilization of the method, the XML file is changed as follows.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd" >
<RequirementInSAT>
   <Version>2.10</Version>
   <NewSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Customer-Retailer</Workflow>
         <Contract>
            <ContractName>WholesaleContract</ContractName>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </NewSAT>
   <ExistingSAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>guest</User>
         <Workflow>Retailer-Wholesaler</Workflow>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
      <SAT>
         <Organization>BigBug.com</Organization>
         <User>customer</User>
         <Workflow>Retailer-Wholesaler</Workflow>
         <Contract>
            <ContractName>CreditCheckingContract</ContractName>
         </Contract>
      </SAT>
   </ExistingSAT>
</RequirementInSAT>

List 16. A more complex XML file for searching example

For example, to search the value of the ContractName tag, which is underlined, all the methods in the above section are not suitable because there is no unique key in the XML file. Because the method provides the parameters to specify multiple key tags and values, it can be used here to deal with this case. The corresponding code is written as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable keyTagHash   = new Hashtable();
Hashtable keyValueHash = new Hashtable();
keyTagHash.put("0",   "Organization");
keyTagHash.put("1",   "User");
keyTagHash.put("2",   "Workflow");
keyTagHash.put("3",   "ContractName");
keyValueHash.put("0", "BigBug.com");
keyValueHash.put("1", "customer");
keyValueHash.put("2", "Retailer-Wholesaler");
keyValueHash.put("3", "?");
String contractName =
       lbXMLOperator.selectByMultipleTagsAndWhere("./xmlfile.xml",
                     keyTagHash, keyValueHash);
Console.WriteLine("contractName = " + contractName);

The result of the above code is displayed as follows.

contractName = CreditCheckingContract
2.4.9 selectByMultipleTagsAndWhereForHash()

Although selectByMultipleTagsAndWhere() is able to handle searching complex XML files, there is a big drawback for it. Sometimes, after specifying all the tags and corresponding values, it is possible that the result is not unique as selectByMultipleTagsAndWhereForHash() expects. To handle this problem, selectByMultipleTagsAndWhereForHash() is a good choice because the result is allowed to be not unique and stored into a Hashtable. The format of the method is as follows, which is similar to selectByMultipleTagsAndWhere() and expects return values.

Hashtable selectByMultipleTagsAndWhereForHash(String xmlFile,
          Hashtable, keyTagHash, Hashtable keyValueHash)

For example, there is an XML file shown in List 17. If users need to retrieve the value of the ExternalPropertyName tag for PC of the Organization, BigBug.com, none of the above methods can be used here. Multiple tags and corresponding values are required to be specified in this case; meanwhile, the searching results are not unique.

<?xml version="1.0"?>
<!DOCTYPE RequirementInSAT SYSTEM "requirement_in_sat.dtd">
<RequirementInSAT>
   <SAT>
      <Organization>
         <OrganizationName>BigBug.com</OrganizationName>
         <External>
            <ExternalDetail>
               <ExternalName>PC</ExternalName>
               <ExternalProperty>
                  <ExternalPropertyName>InStock</ExternalPropertyName>
                  <ExternalPropertyValue>9</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>MerchandisePrice</ExternalPropertyName>
                  <ExternalPropertyValue>399</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
            <ExternalDetail>
               <ExternalName>customer</ExternalName>
               <ExternalProperty>
                 <ExternalPropertyName>UserName</ExternalPropertyName>
                 <ExternalPropertyValue>greatfree</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>Password</ExternalPropertyName>
                  <ExternalPropertyValue>111111</ExternalPropertyValue>
               </ExternalProperty>
               <ExternalProperty>
                  <ExternalPropertyName>CreditCardNumber</ExternalPropertyName>
                  <ExternalPropertyValue>1234567890</ExternalPropertyValue>
               </ExternalProperty>
            </ExternalDetail>
         </External>

List 17. A complex XML file

The code to complete the above searching is shown as follows.

CSharpLBXMLOperator lbXMLOperator = new CSharpLBXMLOperator();
Hashtable keyTagHash   = new Hashtable();
Hashtable keyValueHash = new Hashtable();
keyTagHash.put("0",   "OrganizationName");
keyTagHash.put("1",   "ExternalName");
keyTagHash.put("2",   "ExternalPropertyName");
keyValueHash.put("0", "BigBug.com");
keyValueHash.put("1", "PC");
keyValueHash.put("2", "?");
Hashtable externalPropertyNameHash = new Hashtable();
externalPropertyNameHash =
   lbXMLOperator.getValueByMultipleTagsAndWhereForHash("./xmlfile.xml",
      keyTagHash, keyValueHash);
Console.WriteLine("externalPropertyNameHash = " +
                   externalPropertyNameHash);

After running the code, the result is displayed as follows.

ExternalPropertyNameHash = {1=MerchandisePrice, 0=InStock}
2.4.10 selectByMultipleTagsAndWhereForSet()

selectByMultipleTagsAndWhereForSet() is similar to selectByMultipleTagsAndWhereForHash() expect for the type of return values. By using selectByMultipleTagsAndWhereForSet(), the searching result is stored into a Hashtable for the set instead of a Hashtable. Because those two methods are almost the same, the example for the method is omitted. The format of the method is shown as follows.

Hashtable selectByMultipleTagsAndWhereForSet(String xmlFile,
          Hashtable keyTagHash, Hashtable keyValueHash)

Appendix

  • Tool: LBXML Operator
  • DLL: com.lblabs.xmltool.dll, com.lblabs.tools.csharp.dll
  • Class: CSharpLBXMLOperator
  • Constructor: Summary CSharpLBXMLOperator()

Method Summary

bool insertNodeByParentTag(String xmlFile, String parentTag, String updateTag, String updateValue)
  1. xmlFile: the XML file to be inserted
  2. parentTag: the parentTag of the tag to be inserted
  3. updateTag: the tag to be inserted
  4. updateValue: the value of the tag to be inserted
bool insertNodeParentTagAndParentSibling(String xmlFile, String parentTag, String parentSiblingTag, String parentSiblingValue, String updateTag, String updateValue)
  1. xmlFile: the XML file to be inserted
  2. parentTag: the parentTag of the tag to be inserted
  3. parentSiblingTag: the parent sibling tag of the tag to be inserted
  4. parentSiblingValue: the value of the parent sibling tag of the tag to be inserted
  5. updateTag: the tag to be inserted
  6. updateValue: the value of the tag to be inserted
bool removeNodeByTagValue(String xmlFile, String tag, String value)
  1. xmlFile: the XML file to be removed
  2. tag: the tag to be removed
  3. value: the value of the tag to be removed
bool changeByValue(String xmlFile, String oldValue, String newValue)
  1. xmlFile: the XML file to be changed
  2. oldValue: the value to be modified
  3. newValue: the new value after modification
bool changeByTag(String xmlFile, String tag, String newValue)
  1. xmlFile: the XML file to be changed
  2. tag: the tag to be modified
  3. newValue: the new value after modification
bool changeByTagNewValue(String xmlFile, String tag, String oldValue, String newValue)
  1. xmlFile: the XML file to be changed
  2. tag: the tag to be modified
  3. oldValue: the value to be modified
  4. newValue: the new value after modification
bool changeByNoTagNewValue(String xmlFile, String tag, int no, String newValue)
  1. xmlFile: the XML file to be changed
  2. tag: the tag to be modified
  3. no: the sequential number of the tag to be modified
  4. newValue: the new value after modification
bool hangeBySiblingTagNewValue(String xmlFile, String siblingTag, String siblingValue, String newValue)
  1. xmlFile: the XML file to be changed
  2. siblingTag: the sibling tag of the tag to be modified
  3. siblingValue: t he sibling value of sibling tag of the tag to be modified
  4. newValue: the new value after modification
bool changeBySiblingTagUpdateTagNewValue(String xmlFile, String siblingTag, String siblingValue, String updateTag, String newValue)
  1. xmlFile: the XML file to be changed
  2. siblingTag: the sibling tag of the tag to be modified
  3. updateTag: the tag to be modified
  4. newValue: the new value after modification
bool changeByKeyTagKeyValueUpdateTagNewValue(String xmlFile, String keyTag, String keyValue, String updateTag, String newValue)
  1. xmlFile: the XML file to be changed
  2. keyTag: the key tag of the XML structure the tag to be modified locates
  3. keyValue: the value of the key tag
  4. updateTag: the tag to be modified
  5. newValue: the new value after modification
bool changeByKeyTagKeyValueSiblingTagUpdateTagNewValue(String xmlFile, String keyTag, String keyValue, String siblingTag, String siblingValue, String updateTag, String newValue)
  1. xmlFile: the XML file to be changed
  2. keyTag: the key tag of the XML structure the tag to be modified locates
  3. keyValue: the value of the key tag
  4. siblingTag: the sibling tag of the tag to be modified
  5. siblingValue: the sibling value of the sibling tag
  6. updateTag: the tag to be modified
  7. newValue: the new value after modification
bool changeByMultipleTagsAndWhere(String xmlFile, Hashtable keyTagHash, Hashtable keyValueHash)
  1. xmlFile: the XML file to be changed
  2. keyTagHash: the multiple key tags
  3. keyValueHash: the values of the multiple key tags
String selectByKeyTag(String xmlFile, String keyTag)
  1. xmlFile: the XML file to be searched
  2. keyTag: the tag to be searched
String selectByTagAndWhere(String xmlFile, String keyTag, String searchTag, String keyValue)
  1. xmlFile: the XML file to be searched
  2. keyTag: the key tag of the XML structure the tag to be searched locates
  3. searchTag: the tag to be searched
  4. keyValue: the value of the key tag
String selectByBelowTagAndWhere(String xmlFile, String belowKeyTag, String searchTag, String belowKeyValue)
  1. xmlFile: the XML file to be searched
  2. belowKeyTag: the key tag of the XML structure the tag to be searched locates; the key tag is below the tag to be searched
  3. searchTag: the tag to be searched
  4. belowKeyValue: the value of the belowKeyTag
Hashtable selectHash(String xmlFile, String hashTag)
  1. xmlFile: the XML file to be searched
  2. hashTag: the tag to be searched
Hashtable selectSet(String xmlFile, String setTag)
  1. xmlFile: the XML file to be searched
  2. setTag: the tag to be searched
Hashtable selectByTagAndWhereForHash(String xmlFile, String keyTag, String searchTag, String keyValue)
  1. xmlFile: the XML file to be searched
  2. keyTag: the key tag of the XML structure the tag to be searched locates
  3. searchTag: the tag to be searched
  4. keyValue: the value of the key tag
Hashtable selectByTagAndWhereForSet(String xmlFile, String keyTag, String searchTag, String keyValue)
  1. xmlFile: the XML file to be searched
  2. keyTag: the key tag of the XML structure the tag to be searched locates
  3. searchTag: the tag to be searched
  4. keyValue: the value of the key tag
String selectByMultipleTagsAndWhere(String xmlFile, Hashtable keyHash, Hashtable keyValueHash)
  1. xmlFile: the XML file to be searched
  2. keyHash: the multiple key tags of the XML structure the tag to be seached locates
  3. keyValueHash: the multiple key values of the corresponding key tags
Hashtable selectByMultipleTagsAndWhereForHash(String xmlFile, Hashtable keyHash, Hashtable keyValueHash)
  1. xmlFile: the XML file to be searched
  2. keyHash: the multiple key tags of the XML structure the tag to be seached locates
  3. keyValueHash: the multiple key values of the corresponding key tags
Hashtable selectByMultipleTagsAndWhereForSet(String xmlFile, Hashtable keyHash, Hashtable keyValueHash)
  1. xmlFile: the XML file to be searched
  2. keyHash: the multiple key tags of the XML structure the tag to be seached locates
  3. keyValueHash: the multiple key values of the corresponding key tags

References

  1. XPATH: http://www.w3.org/TR/xpath
  2. GMD-IPSI XQL: http://xml.darmstadt.gmd.de/xql/
  3. XSet: http://www.cs.berkeley.edu/~ravenben/xset/
  4. Fxgrep: http://www.informatik.uni-trier.de/~aberlea/Fxgrep/
  5. Quip: http://developer.softwareag.com/tamino/quip/
  6. XML:QL: http://theoryx5.uwinnipeg.ca/mod_perl/cpan-search?dist=XML-QL


Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Cisco and Intel have harnessed flash memory technology and truly innovative system software to blast through the boundaries of today's I/O-bound server/storage architectures. See how they are bringing real-time responsiveness to data-intensive applications—for unmatched business advantage. Sponsored by Cisco and Intel® Partnering in Innovation

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds