У меня есть сложная структура 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?
Я должен признать, что я не полностью понимаю ваши требования, но я вижу, что:
Мой первоначальный рефлекс был: используйте 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
, но сопоставлять имитирующие шаблоны на основе пути, как кажется в вашем вопросе.
addressLine
иzip
появляются в выходных данных, хотя пути к ним не совпадают? Почему пропущенid
аzip
нет?