У меня есть этот XML:
<?xml version = "1.0" encoding = "UTF-8"?>
<Document>
<tag-one>
<tag-two>
<tag-three>
<tag-four>
<tag-five>
<tag-six>
<tag-seven>
<tag-eight>
<tag-nine>
<id-tag>valid_id</id-tag>
</tag-nine>
</tag-eight>
</tag-seven>
</tag-six>
</tag-five>
</tag-four>
</tag-three>
</tag-two>
<tag-two>
<tag-three>
<tag-four>
<tag-five>
<tag-six>
<tag-seven>
<tag-eight>
<tag-nine>
<id-tag>invalid_id-invalid_kg</id-tag>
</tag-nine>
</tag-eight>
</tag-seven>
</tag-six>
</tag-five>
</tag-four>
</tag-three>
</tag-two>
</tag-one>
</Document>
Я пытаюсь создать файл XSLT, который отфильтровывает элементы tag-two
, если соответствующие им id-tag
содержатся в списке.
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:transform
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes = "#all"
version = "3.0">
<xsl:param name = "invalidIds"/>
<xsl:template match = "@*|node()">
<xsl:copy>
<xsl:apply-templates select = "@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match = "tag-two[contains($invalidIds, tag-three/tag-four/tag-five//*[local-name()='id-tag'])]">
</xsl:template>
</xsl:transform>
Я передаю invalidIds
как список массивов в Java-коде, используя саксонскую библиотеку:
List<String> idList = Arrays.asList("invalid_id-invalid_kg");
// omitted rest of the code for brevity
// Map.of(new QName("invalidIds"), new XdmAtomicValue(idList.toString()))
Когда я распечатал значение invalidIds
в xslt, я получил следующее: [invalid_id-invalid_kg]
.
Проблема в том, что он фильтрует оба tag-two
, потому что похоже, что методы contains
действуют как содержит «Строка», а не как «Массив», а это означает, что «valid_id» соответствует условию... Есть ли у вас какие-либо идеи, как я могу исправить этот?
Да, действительно, в документации все сказано. Возможно, я задал не тот вопрос, я искал решение своей проблемы, а не обходной путь для contains
.
Вы говорите: «Я искал решение своей проблемы» и «Я пытаюсь создать XSLT-файл, который отфильтровывает элементы tag-two, если соответствующий им id-тег содержится в списке». Я думаю, что мой ответ делает это: он показывает вам, как использовать список строк Java в качестве последовательности строк XSLT/XPath/XDM, а затем просто использовать оператор сравнения =
.
Используйте https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/s9api/XdmValue.html#makeSequence(java.lang.Iterable) в своем списке Java, например. Map.of(new QName("invalidIds"), XdmValue.makeSequence(idList))
.
И шаблон должен быть
<xsl:template match = "tag-two[$invalidIds = tag-three/tag-four/tag-five//id-tag]"/>
Начните с чтения спецификации функции, прежде чем писать код, который ее использует. Вы совершенно правы: contains() не делает то, что вы думаете, он делает то, что говорит спецификация.