Можно ли записать экземпляр XMLSchema в родительский тег, а также в дочерний тег?

Я хочу создать ниже XML, который имеет xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" в "ServiceAddRQ", а также тег "Service". ТАК можно ли создать такой XML?

Необходимый XML:

<ServiceAddRQ echoToken="DummyEchoToken" version="2013/12"
  xmlns="http://www.test.com/schemas/2005/06/messages"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com/schemas/2005/06/messages ServiceAddRQ.xsd">  
        <Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ServiceHotel" availToken="1jMqWGjqrx25Bp60gV2Qggb3">
        </Service>
</ServiceAddRQ>

XML, сгенерированный Java: в коде, сгенерированном Java, я получаю пустой xmlns тега "Service"...

<ServiceAddRQ xmlns="http://www.test.com/schemas/2005/06/messages"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" echoToken="6BB6B47EEEF4290515103925"
    version="2013/12"
    xsi:schemaLocation="http://www.test.com/schemas/2005/06/messages HotelValuedAvailRQ.xsd">   
    <Service xmlns="" xsi:type="ServiceHotel" availToken="1/YncBXZJXY17Z/ygNiO7gcg">        
    </Service>
</ServiceAddRQ>

Код Java для того же:

    static private Namespace NSSERVICE = Namespace.getNamespace("http://www.test.com/schemas/2005/06/messages");
    static private Namespace NSSCHEMA = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

        String sXMLOut = "";
        Element barceloDS_requests= new Element("ServiceAddRQ",NSSERVICE);  
            barceloDS_requests.setAttribute("echoToken",searchParams.getSessionID().substring(0, 12)+GenTools.getSystemDateWithTime3());
            barceloDS_requests.setAttribute("version","2013/12");
            barceloDS_requests.addNamespaceDeclaration(NSSCHEMA);
            barceloDS_requests.setAttribute("schemaLocation", "http://www.test.com/schemas/2005/06/messages HotelValuedAvailRQ.xsd", NSSCHEMA);

         Namespace xsi = Namespace.getNamespace(GenTools.returnEmptyForNull(sXMLNS_XSI), "http://www.w3.org/2001/XMLSchema-instance");
         Element eleService=new Element("Service");
            eleService.setAttribute("type", "ServiceHotel", xsi);
            eleService.setAttribute("availToken",contractInfo[1]);
    barceloDS_requests.addContent(eleService);
    sXMLOut = new GetXMLOutputter().getXMLOutputter(barceloDS_requests,true);

person Sumit S Thakur    schedule 29.05.2015    source источник
comment
На вопрос, как я могу изменить свой код для создания X вместо Y, вам действительно нужно показать нам текущий код, который вы хотите изменить... Но обратите внимание, что на самом деле вам не нужно объявление xmlns:xsi в обоих местах, потому что Service элемент автоматически наследует объявления пространства имен своего родителя.   -  person Ian Roberts    schedule 29.05.2015
comment
Привет @IanRoberts, спасибо за ваш ценный ответ. Вы можете проверить мой фрагмент кода Java прямо сейчас. Несмотря на то, что дочерний тег наследует пространство имен родительского тега, почему я получаю пустой «xmlns» в теге службы?   -  person Sumit S Thakur    schedule 29.05.2015
comment
Можете ли вы подтвердить, какую объектную модель XML вы используете здесь, поскольку это определенно не DOM (как в org.w3c.dom). Похоже на JDOM, верно?   -  person Ian Roberts    schedule 29.05.2015
comment
да @IanRoberts, вы абсолютно правы. Я использую JDOM.   -  person Sumit S Thakur    schedule 29.05.2015


Ответы (1)


Сериализатор правильно добавляет xmlns="", потому что вы создали элемент верхнего уровня с объявлением пространства имен по умолчанию, но затем добавили дочерний элемент, которого нет в пространстве имен. Чтобы получить желаемый результат, вам нужно создать элемент Service с тем же пространством имен http://www.test.com/schemas/2005/06/messages, что и корень ServiceAddRQ. Попробуйте еще так:

static private Namespace NSSERVICE = Namespace.getNamespace("http://www.test.com/schemas/2005/06/messages");
static private Namespace NSSCHEMA = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

String sXMLOut = "";
Element barceloDS_requests= new Element("ServiceAddRQ",NSSERVICE);  
barceloDS_requests.setAttribute("echoToken",searchParams.getSessionID().substring(0, 12)+GenTools.getSystemDateWithTime3());
barceloDS_requests.setAttribute("version","2013/12");
barceloDS_requests.addNamespaceDeclaration(NSSCHEMA);
barceloDS_requests.setAttribute("schemaLocation", "http://www.test.com/schemas/2005/06/messages HotelValuedAvailRQ.xsd", NSSCHEMA);

// --------------
// Key change -- Create Service element in the right namespace
Element eleService=new Element("Service",NSSERVICE);
// --------------

eleService.setAttribute("type", "ServiceHotel", NSSCHEMA);
eleService.setAttribute("availToken",contractInfo[1]);
barceloDS_requests.addContent(eleService);

Это создаст правильный вывод:

<ServiceAddRQ echoToken="DummyEchoToken" version="2013/12"
  xmlns="http://www.test.com/schemas/2005/06/messages"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.test.com/schemas/2005/06/messages ServiceAddRQ.xsd">  
    <Service xsi:type="ServiceHotel" availToken="1jMqWGjqrx25Bp60gV2Qggb3"/>
</ServiceAddRQ>

Элемент Service не нуждается в собственном объявлении xmlns:xsi, так как оно наследуется от родителя, но если вы все равно хотите добавить лишнее, это может быть возможным с использованием eleService.addNamespaceDeclaration(NSSCHEMA), но это не гарантирует сериализатор всегда можно опустить избыточные объявления пространств имен, если они не изменяют семантику результата.

person Ian Roberts    schedule 29.05.2015
comment
Привет, @Ian, спасибо за возврат ... учту ваши баллы, упомянутые в удаленном посте, на будущее ... - person Sumit S Thakur; 01.06.2015