2016-04-22 9 views
1

У меня есть простая программа Java, как показано ниже, которая считывает файл XML и выводит его в консоли:В Java 8 префикса пространства имен получает изменен при работе с Woodstox

FileInputStream in = new FileInputStream(new File("/tmp/test.xml")); 
InputStreamReader streamReader = new InputStreamReader(in); 
OMXMLParserWrapper builder = BuilderUtil.getBuilder(streamReader); 

SOAPEnvelope envelope = (SOAPEnvelope)builder.getDocumentElement(); 
//the namespace prefix is OK here (java 7 and java 8) 
System.out.println(envelope.getHeader().getChildrenWithLocalName("Ticket").next()); 

//but after the toString() method, the prefix has modified (java 7 = not change, java 8 = change) 
//attribute mustUnderstand and role 
System.out.println(envelope.toString()); 

XML файл:

<?xml version="1.0" encoding="UTF-8"?> 
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:env="http://www.w3.org/2003/05/soap-envelope"> 
    <S:Header> 
     <abc:Ticket xmlns:abc="somevalue" xmlns:uebernehmeAbschlussdatenXBRL="abcSomevalue" S:mustUnderstand="true" S:role="http://www.w3.org/2003/05/soap-envelope/role/next"> 
      <abc:value>long value</abc:value> 
     </abc:Ticket> 
    </S:Header> 
    <S:Body>  
     <sample>data</sample> 
    </S:Body> 
</S:Envelope> 

Когда я запускаю программу в Java 7 с woodstox-core-asl-4.4.1, stax2-api-3.1.4 и axiom работает нормально. Но когда я бегу то же самое в Java 8, S: роль и S: MustUnderstand разменять как окр: роль и окр: MustUnderstand (S префикс переодеться к окр)

Если удалить woodstox- core-asl-4.4.1 и stax2-api-3.1.4 из программы, он отлично работает и на Java 8.

Здесь я не могу разобраться. Означает ли это, что woodstox не поддерживает Java 8, или я пропустил что-то еще?

+0

Пожалуйста, добавьте информацию о версии Axiom, которую вы используете, и укажите код метода 'BuilderUtil.getBuilder'. –

+0

Я использую версию axiom 1.2.11, которая представляет собой комплект OSGi, встроенный в woodstox –

+0

, почему я получил -1 для этого? –

ответ

2

Префикс S и env в вашем документе обе относятся к тому же пространству имен URI http://www.w3.org/2003/05/soap-envelope.

Таким образом, даже если префикс изменился в сериализованном документе, он по-прежнему эквивалентен префиксу с сохраненными префиксами.

(Причиной изменения может быть в реализации DOM в Java 8, что-то вроде другого упорядочения деклараций пространства имен.)

+0

Да, пространство имен такое же. Но проблема заключается в том, что валидация подписи возвращает false, поскольку префикс был изменен. –

+0

@ThusithaThilinaDayaratne. Почему у вас есть удвоенная декларация пространства имен? – wero

+0

Несмотря на то, что пространство имен одинаково в этом примере, я могу сказать, что может быть ситуация, когда она похожа на xmlns: S = "http://www.w3.org/2003/05/soap-envelope" xmlns: env = "http:// ABC/пример». Я не имею контроля над количеством пространств имен:/ –

1

Одна из основных вещь, чтобы отметить здесь заключается в следующем: с помощью envelope.toString() не очень надежный способ тестирования чего-либо, поскольку неясно, что именно печатается. Woodstox не изменяет префиксы, поэтому маловероятно, что он будет раскрывать другой префикс: более вероятно, что Axiom строит конверт и отображает данное URI пространства имен обратно в другой префикс, учитывая, что есть 2 варианта.

Итак: Я бы предположил, что это связано с изменением JDK, связанным с вычислением хеш-кода String или упорядочением записей HashMap. Учитывая, что существует 2 эквивалентных пространства имен с разными префиксами, упорядочение двух может привести к различному совпадению, когда Axiom запрашивает префикс для данного URI пространства имен; в конце концов, BOTH сопоставляется с тем же префиксом, и поскольку упорядочение атрибутов (из которых объявление префикса пространства имен является частным случаем) не определено в XML (то есть thre не упорядочивает), то один из них действителен

Без зависимости от Woodstox, обработки вероятно, использует JDK-встроенный синтаксический анализатор Stax (sjsxp), и его упорядочение может быть либо случайно стабильным, либо использовать механизм, который не основан на хэше.

+1

Я использовал префикс S и R (вместо env). Тогда он работает без каких-либо проблем. Похоже, что это происходит с вычислением значения хеш-кода в Java 8. Но я до сих пор не могу понять, почему он работает с аксиомой без каких-либо проблем при удалении встроенной зависимости woodstax –

+0

@ThusithaThilinaDayaratne, если Woodstox не включен, обработка, вероятно, будет основана на JDK -элементный анализатор stax (Sjsxp), который может использовать другой механизм и тем самым различный порядок атрибутов и префиксов пространства имен. – StaxMan

0

Неожиданные префиксы вызваны проблемой в старых версиях Apache Axiom (1.2.11 больше 5 лет). Вы должны перейти на 1.2.15 или более позднюю версию.

Аксиома использовала HashMap для хранения деклараций пространства имен; это может быть причиной того, что для данного сообщения вы видите только проблему с некоторыми версиями Java.

+0

Спасибо за информацию. Да. Кажется, что проблема исправлена ​​в аксиоме 1.2.15. Не могли бы вы указать на джиру или исправить? :) Я проверил примечание о выпуске, но не смог найти точное исправление. Https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311190&version=12318876 –

+0

К сожалению, нет. Я помню, что я исправил несколько проблем, связанных с пространством имен, но я думаю, что они не были сообщены как вопросы JIRA; они пришли во время отладки других проблем или пересмотра/рефакторинга кода. Если вам действительно нужно идентифицировать точный фиксатор, который исправил проблему, вам нужно было бы использовать что-то вроде git bisect. –

+0

, что грустно :(Я постараюсь проверить это. Спасибо за информацию @Anreas. Вы случайно помните, какой пакет или класс вы исправили?), Если да, пожалуйста, дайте мне знать. Как я понимаю, это вызвано изменениями в hanshcode в JDK + некоторая ошибка в аксиоме? –