1

Below is the XML I have

     <TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="{Settings:Tenant}" PolicyId="B2C_1A_User_MigrationClients" PublicPolicyUri="http://{Settings:Tenant}/B2C_1A_User_MigrationClients" DeploymentMode="{Settings:DeploymentMode}" UserJourneyRecorderEndpoint="urn:journeyrecorder:applicationinsights">
          <BuildModel>
                 <RestSchema>
                        <CustType Id="regular.type1">
                              <DataType>string</DataType>
                        </CustType>
                        <CustType Id="regular.type2">
                              <DataType>string</DataType>
                        </CustType>

                 </RestSchema>
          </BuildModel>
    </TrustFrameworkPolicy>

I have to add new nodes under "RestSchema"

This is how I want to create new

   <TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="{Settings:Tenant}" PolicyId="B2C_1A_User_MigrationClients" PublicPolicyUri="http://{Settings:Tenant}/B2C_1A_User_MigrationClients" DeploymentMode="{Settings:DeploymentMode}" UserJourneyRecorderEndpoint="urn:journeyrecorder:applicationinsights">
           <BuildModel>
             <RestSchema>
                    <CustType Id="regular.type1">
                          <DataType>string</DataType>
                    </CustType>
                    <CustType Id="regular.type2">
                          <DataType>string</DataType>
                    </CustType>
                    <CustType Id="regular.Command-Nest.type1">
                          <DataType>string</DataType>
                    </CustType>
                    <CustType Id="regular.Command-Nest.type2">
                          <DataType>string</DataType>
                    </CustType>
             </RestSchema>
      </BuildModel>
</TrustFrameworkPolicy>

How can I do it using XPATH. I have to create this type of structure in the EXISTING XML under.

I know how to track down to the tag I just need to know how I can create these in java using XPATH.

    private static void addNewCustType(String updatedXMLPath) throws Exception {
        
        System.out.println("Adding new claim types.");
        
        Document document = getXmlAsDocument(updatedXMLPath);
        
        for (int i = 0; i < newClaim.size() ; i++ ) {
            
            // This is how I am traversing to the TAG where I need to add
            String expression = "/*[local-name() = 'TrustFrameworkPolicy']/*[local-name() = 'BuildModel']/*[local-name() = 'RestSchema']";
            
            // I need to understand how I can create a node under "above" path...
            

        }
    }

    private static Document getXmlAsDocument(String fileName) throws Exception {
    
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(fileName);
            return doc;
        }
1
  • Doing manual XML alteration is a not the right way to go. You should create a class structure and annotate with XMLRootElement, XMLElement, etc and allow the marshaller to do the work. Commented Apr 15, 2021 at 14:06

1 Answer 1

1

This should do the trick. Written from the top of my head and untested. I already know it only applies without namespace. So you can verify that it works first by stripping off the namespaces from your document. Then add them again, modifying the code so that it matches.

Document document = getXmlAsDocument(updatedXMLPath);
XPath xpath = XPathFactory.newInstance().newXPath();
Element restSchema = (Element)xpath.evaluate("/TrustFrameworkPolicy/BuildModel/RestSchema", document, XPathConstants.NODE);

Element dataType = document.createElement("DataType");
dataType.appendChild(document.createText("string");
Element custType = document.createElement("CustType");
custType.setAttribute("Id", "regular.Command-Nest.type1");
custType.appendChild(dataType);
restSchema.appendChild(custType);

// finally serialize using the identity transformer

For namespaces you have to make two changes:

  • instead of using createElement, use createElementNS
  • instead of using the simple xpath I used, you need to use namespace prefixes and provide a NamespaceContext to the xpath engine.
Sign up to request clarification or add additional context in comments.

1 Comment

I have already finished it, Will update what I did in sometime. Thanks for this, might help the community. :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.