【问题标题】:XSLT Transformation to output a element if not present in the source, if present leaving as it isXSLT 转换以输出一个元素(如果源中不存在),如果存在则保持原样
【发布时间】:2014-09-24 10:03:47
【问题描述】:

基本上我有源 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>

【问题讨论】:

    标签: java xslt xml-parsing saxon


    【解决方案1】:

    我认为问题在于在身份模板上使用“优先级”属性

    <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>
    

    请注意,我也在ChildComplexType1 模板中添加了xsl:copy,但您似乎正在使用您在问题中未提及的命名空间,因此您可能需要将其更改为xsl:element .

    注意,有关模板优先级的信息,请参阅http://www.w3.org/TR/xslt#conflict。特别要注意最高的默认优先级是 0.5。

    【讨论】:

      【解决方案2】:

      您似乎正在使用身份模板。

      您可以在此处查看此页面,该页面对模板的描述非常详尽。

      http://www.xmlplease.com/xsltidentity#s1.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 2017-02-05
        • 1970-01-01
        • 2021-04-05
        • 2019-08-20
        • 1970-01-01
        • 2016-04-16
        相关资源
        最近更新 更多