All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.oxm.annotations.XmlPath Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Matt MacIvor = 2.1 - Initial contribution
package org.eclipse.persistence.oxm.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * XPath based mapping is what allows an existing object model to be mapped
 * to an existing XML schema. The {@literal @XmlPath} annotation is the means by
 * which XPath based mapping is achieved.
 *
 * 

Example 1 - Using {@literal @XmlPath} to Add a Grouping Element *

Sometimes grouping elements are added to your document to organise data. JAXB has this concept * for collection properties in the form of {@linkplain jakarta.xml.bind.annotation.XmlElementWrapper}. * Here we'll use {@literal @XmlPath} for non-collection properties. * In this case we'll nest the billing/shipping address data within the "contact-info" element.

* {@snippet : * import jakarta.xml.bind.annotation.*; * import org.eclipse.persistence.oxm.annotations.XmlPath; * * @XmlRootElement * @XmlAccessorType(XmlAccessType.FIELD) * public class Customer { * @XmlPath("contact-info/billing-address") * private Address billingAddress; * * @XmlPath("contact-info/shipping-address") * private Address shippingAddress; * } * } * This will produce XML like: * {@snippet lang="XML": * * <customer> * <contact-info> * <billing-address> * <street>1 Billing Street</street> * </billing-address> * <shipping-address> * <street>2 Shipping Road</street> * </shipping-address> * </contact-info> * </customer> * * } * *

Example 2 - Using {@literal @XmlPath} to Map by Position *

Normally in JAXB elements with the same name must be mapped to a collection property. * Using the {@literal @XmlPath} extension you map non-collection properties to a repeated element by index.

* {@snippet : * import jakarta.xml.bind.annotation.*; * import org.eclipse.persistence.oxm.annotations.XmlPath; * * @XmlRootElement * @XmlAccessorType(XmlAccessType.FIELD) * public class Customer { * @XmlPath("address[1]") * private Address billingAddress; * * @XmlPath("address[2]") * private Address shippingAddress; * } * } * This will produce XML like: * {@snippet lang="XML": * * <customer> * <address> * <street>1 Billing Street</street> * </address> * <address> * <street>2 Shipping Road</street> * </address> * </customer> * * } * *

Example 3 - Using {@literal @XmlPath} to Map Two Objects to the Same Node *

We have seen how {@literal @XmlPath} can be used to expand the structure by adding a grouping element. * {@literal @XmlPath} can also be used to collapse the structure by mapping two objects to the same node.

* {@snippet : * import jakarta.xml.bind.annotation.*; * import org.eclipse.persistence.oxm.annotations.XmlPath; * * @XmlRootElement * @XmlAccessorType(XmlAccessType.FIELD) * public class Customer { * @XmlPath(".") * private Address billingAddress; * * private Address shippingAddress; * } * } * This will produce XML like: * {@snippet lang="XML": * * <customer> * <street>1 Billing Street</street> * <shippingAddress> * <street>2 Shipping Road</street> * </shippingAddress> * </customer> * * } */ @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(XmlPaths.class) public @interface XmlPath { /** * The XPath for this property. A subset of the XPath specification may be * used to specify mappings. The following concepts are supported: *
    *
  • Attribute - "@id"
  • *
  • Element - "address"
  • *
  • Element by Position - "address[1]"
  • *
  • Element by Predicate - "address[@type='mailing']"
  • *
  • Element Text - "name/text()"
  • *
  • Text - "text()"
  • *
  • Self - "."
  • *
  • Combination - "personal-info/name[2]/text()"
  • *
*

For namespace qualified nodes, the prefixes defined in the {@linkplain jakarta.xml.bind.annotation.XmlNs} * annotations can be used to qualify the XPath fragments. Unqualified * fragments will assumed to be in the namespace specified using * {@linkplain jakarta.xml.bind.annotation.XmlSchema}.

*

Example: *

Assuming the following namespace information has been set up using the * {@linkplain jakarta.xml.bind.annotation.XmlSchema} annotation:

* {@snippet : * @XmlSchema(namespace = "https://www.example.org/FOO", * xmlns = {@XmlNs(prefix="ns", namespaceURI="https://www.example.com/BAR")}, * elementFormDefault = XmlNsForm.QUALIFIED) * package org.example; * * import jakarta.xml.bind.annotation.*; * } *

Then the following XPath:

* {@snippet : * @XmlPath("contact-info/ns:address/@id") * } *

Will be qualified as:

*
    *
  • contact-info - in "https://www.example.org/FOO" namespace.
  • *
  • address - in "https://www.example.com/BAR" namespace.
  • *
  • @id - in no namespace.
  • *
* @see jakarta.xml.bind.annotation.XmlSchema * @see jakarta.xml.bind.annotation.XmlNs */ String value(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy