хранить только нужные элементы в xml с указанным списком xpath

1

У меня есть сложная структура xml. Несколько раз я хочу, чтобы только элементы соответствовали моему списку элементов xpath.

Образец xml


 <Employee>
    <Address>
        <addressLine1>Dummy Line 1</addressLine1>
        <zip>535270</zip>
    </Address>
    <Department>
        <id>102</id>
        <name>development</name>
    </Department
</Employee>

Образцы записей xpath могут быть временем

//Employee/Address
//Employee/Department/
//Employee/Department/name

В приведенном выше xpath, если вы наблюдаете, у нас есть Департамент и Имя внутри отдела, тогда в этом случае я могу игнорировать Department.Also выше записей xpath могут быть как ниже

//Employee/Address
//Employee/Department/name

Результирующий xml я хочу как ниже

<Employee>
    <Address>
        <addressLine1>Dummy Line 1</addressLine1>
        <zip>535270</zip>
    </Address>
    <Department>
        <name>development</name>
    </Department
</Employee>

Я понял, что могу достичь этого через xslt. Поэтому я хочу xslt для такого рода общих требований. Также мой текущий код находится в java. Есть ли лучшая альтернатива в java?

  • 0
    « Я понял, что могу достичь этого с помощью xslt. » Не так просто, если во время выполнения пути передаются в виде строк .
  • 2
    Можете ли вы объяснить более подробно, почему addressLine и zip появляются в выходных данных, хотя пути к ним не совпадают? Почему пропущен id а zip нет?
Показать ещё 1 комментарий
Теги:
xpath
xslt
dom

1 ответ

0

Я должен признать, что я не полностью понимаю ваши требования, но я вижу, что:

  • У вас есть набор XPath
  • Кажется, вы хотите получить объединение этих операторов XPath, если они применяются к вашему входному документу
  • Дубликаты удалены (точно так же, как выражение объединения XPath)
  • Некоторая магия об определенных элементах, которые могут появиться, даже если они не указаны в списке операторов XPath.

Мой первоначальный рефлекс был: используйте xsl:evaluate, но, учитывая, что вы укореняете все ваши выражения XPath, это может не дать вам желаемых результатов. Кроме того, для этого требуется процессор XSLT 3.0.

С XSLT 2.0 вы можете сделать что-то вроде этого:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" 
    version="2.0">

    <xsl:strip-space elements="*" />

    <xsl:output indent="yes" />

    <xsl:variable name="patterns" as="xs:string*">
        <xsl:sequence select="(
            'foo/bar',
            'foo/test',
            'foo/bar/zed')" />
    </xsl:variable>

    <xsl:template match="node()[true() = (
        for $p in $patterns 
        return ends-with(
            string-join(current()/ancestor-or-self::*/name(), 
            '/'), $p))]">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="text()" />

</xsl:stylesheet>

Это просто означает, что вы начнете, это не значит, что это полноценное решение. Он соответствует XPath для создания //QName/QName, как тот, который приведен в вашем примере. Я удалил trailing // и просто совпадал, когда текущий путь соответствует любому из путей (с учетом неявного потомка или себя, как в вашем примере).

Вероятно, вы хотите включить выражение for-expression в функцию и вызвать функцию для сопоставления конкатенации текущего пути с любым из ваших путей в вашем списке.

В его текущей форме вам также потребуется указать пути, ведущие к более глубокому пути, или вам придется реализовать функцию fn:snapshot -like для копирования узлов-предков.

Во всяком случае, я думаю, что это достаточно простой подход, чтобы подражать не обязательно xsl:evaluate, но сопоставлять имитирующие шаблоны на основе пути, как кажется в вашем вопросе.

  • 0
    При этом я получаю только листовые элементы
  • 0
    @mohan, вот почему я написал: «В его текущей форме вам также нужно будет указать пути, ведущие к более глубокому пути, или вам придется реализовать функцию, подобную fn: snapshot, для копирования узлов-предков». , Это естественно, потому что вы не можете соответствовать тому, чего не знаете (предки не соответствуют шаблонам, пока не достигнут более глубокого уровня).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню