【问题标题】:add an element to a node, if it doesnot exist将元素添加到节点,如果它不存在
【发布时间】:2018-03-07 07:01:57
【问题描述】:

使用 xslt-3,

我尝试插入元素 PROPERTY,如果它不存在于每个 RECORD 节点:

<?xml ="1.0" encoding="UTF-8"?>
    <TABLE NAME="TABLE.DB">
        <DATA RECORDS="2">
            <RECORD ID="1">
                <RECNO>1</RECNO>
                <SEQ>0</SEQ>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <ORDER>10355</ORDER>
                <CN>PL</CN>
            </RECORD>
            <RECORD ID="2">
                <RECNO>2</RECNO>
                <SEQUENCE>0</SEQUENCE>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <ORDER>10356</ORDER>
                <CN>PL 300 L</CN>
            </RECORD>
            <RECORD ID="3">
                <RECNO>3</RECNO>
                <SEQUENCE>0</SEQUENCE>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <NUMBER>10357</NUMBER>
                <CN>PL 300 L</CN>
                <PROPERTY>0</PROPERTY>
            </RECORD>
        </DATA>
    </TABLE>

想要的结果:

  <?xml ="1.0" encoding="UTF-8"?>
    <TABLE NAME="TABLE.DB">
        <DATA RECORDS="2">
            <RECORD ID="1">
                <RECNO>1</RECNO>
                <SEQ>0</SEQ>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <ORDER>10355</ORDER>
                <CN>PL</CN>
                <PROPERTY>06</PROPERTY>
            </RECORD>
            <RECORD ID="2">
                <RECNO>2</RECNO>
                <SEQUENCE>0</SEQUENCE>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <ORDER>10356</ORDER>
                <CN>PL 300 L</CN>
                <PROPERTY>06</PROPERTY>
            </RECORD>
            <RECORD ID="3">
                <RECNO>3</RECNO>
                <SEQUENCE>0</SEQUENCE>
                <DATE>17/12/1999 2:44:08 μμ</DATE>
                <ID>12/11/2015 3:15:25 μμ</ID>
                <NUMBER>10357</NUMBER>
                <CN>PL 300 L</CN>
                <PROPERTY>0</PROPERTY>
            </RECORD>
        </DATA>
    </TABLE>

我尝试过添加元素属性,即使它已经存在,所以我最终会在同一个节点中得到两个元素属性,如果它已经存在的话。你能给我一个示例实现吗,我使用 SAXON 最新版本(9.8)

编辑: 下面的 xsl 添加一个元素,即使存在一个元素:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="xsl exsl xs">
    <xsl:output method="xml" version="1.0" indent="yes" encoding="utf-8" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="//*[local-name() = 'RECORD ID']">
        <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
            <xsl:choose>
                <xsl:when test="not(PRODUCT)">
                    <PRODUCT><xsl:value-of select="98"/></PRODUCT>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy><xsl:value-of select="98"/></xsl:copy>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 即使在 XSLT 1.0 中听起来也很简单,编写一个模板 xsl:template match="RECORD[not(PROPERTY)]/*[last()]" 在其中复制该元素并添加新的 PROPERTY
  • 学习 XSLT-3,这就是为什么我要求 XSLT-3 实现,谢谢
  • 添加节点的方式在 XSLT 1 或 2 或 3 中没有什么不同,在 XSLT 3 中,使用&lt;xsl:mode on-no-match="shallow-copy"/&gt; 可以更轻松地开始,而不是拼写身份转换。试一试,然后向我们解释如果你没有让它发挥作用,你到底在哪里卡住了。
  • 补充了我不足的尝试

标签: xml xslt-2.0 xslt-3.0


【解决方案1】:

身份转换可以使用xsl:mode 编写,然后您只需添加一个模板匹配RECORD[not(PROPERTY)]/*[last()]RECORDs 的最后一个子元素,没有PROPERTY)复制最后一个子元素并添加一个新PROPERTY:

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

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:param name="new-prop" as="element(PROPERTY)"><PROPERTY>98</PROPERTY></xsl:param>

    <xsl:template match="RECORD[not(PROPERTY)]/*[last()]">
        <xsl:copy-of select="., $new-prop"/>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

  • 上面的工作就像一个魅力,只有一点点注意,它与前一个元素在同一行中添加了 98
  • 添加 &lt;xsl:output indent="yes"/&gt; 应该会给你缩进,可能有助于与 &lt;xsl:strip-space elements="*"/&gt; 一起做到这一点以获得最一致的结果。
  • 非常感谢,两个都加了,效果很理想。
【解决方案2】:

另一种方法是

<xsl:param name="new-prop" as="element(PROPERTY)">
  <PROPERTY>98</PROPERTY>
</xsl:param>

<xsl:template match="RECORD">
  <RECORD ID="{@ID}">
    <xsl:copy-of select="* except PROPERTY, (PROPERTY, $new-prop)[1]"/>
  </RECORD>
</xsl:template>

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多