2016-09-04 1 views
1

У меня есть сторонний XML для анализа в следующей форме. Количество тестов неограничено, но всегда целое число.Анализ XML с именами структурированных элементов

<tests> 
    <test_1> 
     <foo bar="baz" /> 
    </test_1> 

    <test_2> 
     <foo bar="baz" /> 
    </test_2> 

    <test_3> 
     <foo bar="baz" /> 
    </test_3> 
</tests> 

В настоящее время я разбираю это с помощью XPath, но это очень много возиться. Есть ли способ выразить этот стиль XML в схеме XSD и генерировать классы JAXB из него.

Насколько я вижу, это невозможно, единственное, что возможно, это техника <xs:any processContents="lax"/> от how can I define an xsd file that allows unknown (wildcard) elements? , однако это позволяет использовать любой контент, а не только <test_<integer>. Я просто хочу подтвердить, что я не пропустил трюк XSD/JAXB?

Примечание. Я бы предпочел, чтобы XML был структурирован таким образом. Я могу попытаться убедить третью сторону изменить.

<tests> 
    <test id="1"> 
     <foo bar="baz" /> 
    </test> 

    <test id="2"> 
     <foo bar="baz" /> 
    </test> 

    <test id="3"> 
     <foo bar="baz" /> 
    </test> 
</tests> 
+0

XSD сосредоточены вокруг фиксированного набора элементов/типов. JAXB просто создает классы из них. Как определить число различных элементов с помощью схемы именования «test_xxx»? --- Однако я вижу альтернативу: сначала используйте XSLT, чтобы изменить входящий XML с этими элементами на тот, который соответствует вашим потребностям, и использует схему именования '. Для этого вы можете легко написать XSD и сгенерировать классы JAXB. – Seelenvirtuose

ответ

1

Хотя есть способы борьбы с элементами со структурированными именами, такими как числовые суффиксы,

вы действительно должны исправить основной дизайн XML (test_1 должен быть test) вместо этого.

0

Для полноты здесь полный рабочий пример использования XSLT для преобразования <test_N> входа в <test id="N"> стиль

<tests> 
    <test_1> 
     <foo bar="baz" /> 
    </test_1> 
    <test_2> 
     <foo bar="baz" /> 
    </test_2> 
    <test_1234> 
     <foo bar="baz" /> 
    </test_1234> 
    <other> 
     <foo></foo> 
    </other> 
</tests> 

XSL

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[substring(name(), 1, 5) = 'test_']"> 
     <xsl:element name="test"> 
      <xsl:attribute name="id"><xsl:value-of select="substring(name(), 6, string-length(name()) - 5)" /></xsl:attribute> 
      <xsl:copy-of select="node()" /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Код

File input = new File("test.xml"); 
File stylesheet = new File("test.xsl"); 

StreamSource stylesource = new StreamSource(stylesheet); 
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource); 
StringWriter writer = new StringWriter(); 
transformer.transform(new StreamSource(input), new StreamResult(writer)); 

System.out.println(writer); 

Выход

<?xml version="1.0" encoding="UTF-8"?> 
<tests> 
    <test id="1"> 
     <foo bar="baz"/> 
    </test> 

    <test id="2"> 
     <foo bar="baz"/> 
    </test> 

    <test id="1234"> 
     <foo bar="baz"/> 
    </test> 

    <other> 
     <foo/> 
    </other> 
</tests>