XSLT Преобразование для вывода элемента, если он отсутствует в источнике, если он присутствует, оставив его без изменений.
В основном у меня есть исходный XML
<RootElement attr=yes>
<parentElement>
<ChildElement1>some value in str</ChildElement1>
<ChildElement2>some value in str</ChildElement2>
<ChildComplexType1>
<grandChildElement1>some value in str</grandChildElement1>
</ChildComplexType1>
</parentElement>
</RootElement>
Я использую XSLT, чтобы изменить его на какой-то другой XML. Потребитель, получающий XML-результат, ожидает, как показано ниже
<RootElement attr=yes>
<parentElement>
<ChildElement1>some value in str</ChildElement1>
<ChildElement2>some value in str</ChildElement2>
<ChildComplexType1>
<grandChildElement1>some value in str</grandChildElement1>
<grandChildElement2>Default Value/ From Source XML</grandChildElement2>
</ChildComplexType1>
</parentElement>
</RootElement>
Проблема в том, что я использую приведенное ниже правило соответствий, и оно не работает. Кто-нибудь может предложить лучшее правило, которое работает? Я считаю, что это основной вопрос, извиняюсь, так как я новичок в XSLT.
<xsl:template match="@*|node()" priority="1">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*:parentElement"
priority="2">
<xsl:element name="{name()}"
namespace="http://namespace"
inherit-namespaces="no">
<xsl:namespace name="ns5"
select="'namespace'" />
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="*:ChildComplexType1">
<xsl:if test="not(*:grandChildElement2)" priority="3">
<grandChildElement2>defaultValue</grandChildElement2>
</xsl:if>
<xsl:apply-templates />
</xsl:template>
2 ответа
Я думаю, что проблема с использованием атрибута "priority" в шаблоне идентификации
<xsl:template match="@*|node()" priority="1">
Это дало ему более высокий приоритет, чем сопоставление с шаблоном *::ChildComplexType1
и поэтому этот шаблон никогда не совпадает.
Попробуйте удалить приоритеты, вот так:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*:parentElement">
<xsl:element name="{name()}"
namespace="http://namespace"
inherit-namespaces="no">
<xsl:namespace name="ns5"
select="'namespace'" />
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="*:ChildComplexType1">
<xsl:copy>
<xsl:apply-templates />
<xsl:if test="not(*:grandChildElement2)">
<grandChildElement2>defaultValue</grandChildElement2>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, что я добавил xsl:copy
к ChildComplexType1
шаблон, но вы, кажется, делаете что-то с пространствами имен, которые вы не упомянули в своем вопросе, поэтому вам может потребоваться изменить это на xsl:element
вместо.
Обратите внимание, см. http://www.w3.org/TR/xslt для получения информации о приоритете шаблона. В частности, обратите внимание, как самый высокий приоритет по умолчанию равен 0,5.
Кажется, вы используете шаблон идентификации.
Вы можете посмотреть на эту страницу, которая довольно подробно описывает шаблон.