Преобразование файлов xml и xsd в файл csv с использованием Java и файла xsl

Как сказано в заголовке, у меня есть файлы xml и xsd, и я хочу преобразовать их в файл csv с помощью Java и структурировать его с помощью файла xsl.

На данный момент я могу только преобразовать свой XML-файл и структурировать его с помощью XSL-файла с помощью этого кода в Java:

public static void xmlToCSV() throws Exception{
        File stylesheet = new File("style.xsl");
        File xmlSource = new File("xmlData.xml");

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(xmlSource);

        StreamSource stylesource = new StreamSource(stylesheet);
        Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
        Source source = new DOMSource(document);
        Result outputTarget = new StreamResult(new File("output.csv"));
        transformer.transform(source, outputTarget);
    }

sytle.xsl:

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema">

  <xsl:template match = "Person">
    <xsl:value-of select = "Name"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select = "Gender"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select = "Age"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

xmlData.xml:

<?xml version = "1.0" encoding = "UTF-8"?>
<Document>
    <Person>
        <Name>Bob</Name>
        <Gender>m</Gender>
        <Age>19</Age>
    </Person>
</Document>

Выход:

Боб, м, 19

В моем xsd вы можете увидеть некоторые ограничения, которые я хочу иметь в своем CSV-файле:

 <xs:element maxOccurs = "1" minOccurs = "1" name = "Name">
 <xs:element maxOccurs = "1" minOccurs = "1" name = "Gender">
 <xs:element maxOccurs = "1" minOccurs = "0" name = "Age">

Что я хочу:

name,min,max,value
Bob,1,1,Name
m,1,1,Gender
19,0,1,Age

Я новичок в xsl и не знаю, как и где использовать xsd. Я видел что-то об импорте xsd в ваш xsl-файл, но мне это не помогло. Надеюсь, я не забыл важную информацию. Спасибо за помощь.

Вы не можете применить XSL/XSD к CSV. Если вы хотите преобразовать XML в CSV, вам придется проанализировать XML, преобразовать его вручную, а затем записать CSV.

Jorn 05.10.2023 11:45

@Jorn Конечно, возможно преобразовать XML в CSV с помощью преобразования XSL, как доказал автор.

Karsten 05.10.2023 11:52

XSLT 2/3 обеспечивает обработку с учетом схемы, но обычно это поддерживается только корпоративным программным обеспечением, таким как Saxon EE? Вы используете, например. oXygen, у вас есть доступ к Saxon EE для запуска XSLT 2/3 с поддержкой схемы?

Martin Honnen 05.10.2023 12:01

Вы можете передать путь к документу XSD в качестве параметра таблицы стилей XSLT и указать таблице стилей читать оттуда значения minOccurs и maxOccurs на основе совпадающих имен элементов. Точные сведения зависят от того, какую версию XSLT поддерживает ваш процессор.

michael.hor257k 05.10.2023 12:01

@MartinHonnen, возраст 9 лет был просто ошибкой с моей стороны. Отредактировано :) И нет, у меня нет такого корпоративного программного обеспечения.

Akito The Duck 05.10.2023 12:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуй это:

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:xs = "http://www.w3.org/2001/XMLSchema">

  <xsl:output method = "text"/>

  <!--  strip-space: so we have not unwanted linefeeds-->
  <xsl:strip-space elements = "*"/>
  
  <!--  document(the uri to the schema.xsd)-->
  <xsl:variable name = "schema" select = "document('some.xsd')"/>
  <xsl:key name = "schema-key" match = "xs:element" use = "@name" />

  <xsl:template match = "/">
    <xsl:text>name,min,max,value</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select = "Document/Person"/>
  </xsl:template>

  <xsl:template match = "Person/*">
    <xsl:variable name = "elementName" select = "name()"/>
    <xsl:value-of select = "text()"/>
    <xsl:text>,</xsl:text>
    <!--  To use a key on a external document in xslt 1.0 we have to change the context to that document -->
    <xsl:for-each select = "$schema">
      <xsl:variable name = "schemaElement" select = "key('schema-key', $elementName)"/>
      <xsl:value-of select = "$schemaElement/@minOccurs"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select = "$schemaElement/@maxOccurs"/>
      <xsl:text>,</xsl:text>
    </xsl:for-each>
    <xsl:value-of select = "$elementName"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

даст вам желаемый результат:

name,min,max,value
Bob,1,1,Name
m,1,1,Gender
19,0,1,Age

У меня это получилось без проблем. Спасибо за помощь :)

Akito The Duck 06.10.2023 16:03

Другие вопросы по теме