使用xslt 2.0

时间:2018-05-20 23:17:20

标签: xml xslt

我在转换xml时遇到了困难。这是我的xml:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <organisation>
        <school>
            <name>school of arts Berlin</name>
            <address>123street</address>
        </school>
    </organisation>
    <teachers>
        <wo_number>34A</wo_number>
        <publication>
            <date>14-09-2018</date>
            <name>J. doe</name>
        </publication>
        <teacher id="A254">
            <situation>
                <ill>yes</ill>
            </situation>
            <situation>
                <ill>no</ill>
            </situation>
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="A254">
            <situation>
                <ill>yes</ill>
            </situation>
            <situation>
                <ill>yes</ill>
            </situation>
        </teacher>
        <teacher id="B254">
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="X92">
            <situation>
                <ill>no</ill>
            </situation>
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="G56">
            <situation>
                <ill>probable</ill>
            </situation>
            <situation>
                <ill>no</ill>
        </situation>
        </teacher>
        <teacher id="G56">
            <situation>
                <ill>yes</ill>
            </situation>
        </teacher>
        <teacher id="G56">
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
    </teachers>
</root>

我想要实现的目标:

  • teacher元素有一个属性id,如果它以&#34; A2&#34;并且同一教师节点内元素的文本内容等于&#34;是&#34;必须删除情境节点。如果教师节点中没有剩余节点,则必须删除教师节点
  • teacher元素有一个属性id,如果它以&#34; G5&#34;并且同一教师节点内元素ill的文本内容等于&#34;可能&#34;必须删除情境节点。如果教师节点中没有剩余节点,则必须删除教师节点

正确的结果应该是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <organisation>
        <school>
            <name>school of arts Berlin</name>
            <address>123street</address>
        </school>
    </organisation>
    <teachers>
        <wo_number>34A</wo_number>
        <publication>
            <date>14-09-2018</date>
            <name>J. doe</name>
        </publication>
        <teacher id="A254">
            <situation>
                <ill>no</ill>
            </situation>
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="B254">
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="X92">
            <situation>
                <ill>no</ill>
            </situation>
            <situation>
                <ill>probable</ill>
            </situation>
        </teacher>
        <teacher id="G56">
            <situation>
                <ill>no</ill>
            </situation>
        </teacher>
        <teacher id="G56">
            <situation>
                <ill>yes</ill>
            </situation>
        </teacher>
    </teachers>
</root>
到目前为止,我还没有能够实现这个目标。我的xslt现在是:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:output omit-xml-declaration="yes"/>

      <xsl:template match="node()|@*">
          <xsl:copy>
              <xsl:apply-templates select="node()|@*"/>
          </xsl:copy>
      </xsl:template>
      <xsl:template match="teacher[starts-with(@id,'A2') and situation/ill='yes']"/>
      <xsl:template match="teacher[starts-with(@id,'G5') and situation/ill='probable']"/>
    </xsl:stylesheet>

结果如下:

    <root>
        <organisation>
            <school>
                <name>school of arts Berlin</name>
                <address>123street</address>
            </school>
        </organisation>
        <teachers>
            <wo_number>34A</wo_number>
            <publication>
                <date>14-09-2018</date>
                <name>J. doe</name>
            </publication>


            <teacher id="B254">
                <situation>
                    <ill>probable</ill>
                </situation>
            </teacher>
            <teacher id="X92">
                <situation>
                    <ill>no</ill>
                </situation>
            </teacher>
            <teacher id="G56">
                <situation>
                    <ill>yes</ill>
                </situation>
            </teacher>

        </teachers>
    </root>

所有教师节点都有 id="A254"被删除,这是不正确的,删除​​了id="G56"的教师节点,这也是不正确的。一些帮助将受到高度赞赏。

3 个答案:

答案 0 :(得分:4)

作为替代方案,当您正在寻找XSLT 2解决方案时,您可能会使用Saxon 9或Altova,其中最新版本也支持XSLT 3,您可以使用XSLT 3 xsl:where-populated https://www.w3.org/TR/xslt-30/#element-where-populated确保只有那些通过子项处理创建内容的teacher元素才能创建输出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

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

  <xsl:template match="teacher[starts-with(@id, 'A2')] | teacher[starts-with(@id, 'G5')]">
      <xsl:where-populated>
          <xsl:next-match/>
      </xsl:where-populated>
  </xsl:template>

  <xsl:template match="teacher[starts-with(@id, 'A2')]/situation[ill = 'yes'] |
                       teacher[starts-with(@id, 'G5')]/situation[ill = 'probable']"/>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/gWmuiJ9的在线演示。

答案 1 :(得分:2)

此解决方案需要对空模板进行一些微调。

前两个模板会检查teacher元素是否包含yes个孩子中的所有probablesituation/ill值,如果是,请将其删除。通过将孩子的数量与匹配的孩子的数量进行比较来执行检查。

其他两个模板会检查situation元素,其中只有一个ill元素包含yesprobable。如果是,则仅删除situation元素,而不删除整个teacher元素。

<xsl:template match="teacher[starts-with(@id,'A2') and situation/ill='yes' and count(situation[ill='yes']) = count(situation/ill)]" />      
<xsl:template match="teacher[starts-with(@id,'G5') and situation/ill='probable' and count(situation[ill='probable']) = count(situation/ill)]" />
<xsl:template match="situation[starts-with(../@id,'A2') and ill='yes']"/>      
<xsl:template match="situation[starts-with(../@id,'G5') and ill='probable']"/>   

答案 2 :(得分:1)

<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:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="root">
        <xsl:element name="root">
        <xsl:element name="organisation">
            <xsl:element name="school">
                <xsl:element name="name">
                    <xsl:value-of select="organisation/school/name"/>
                </xsl:element>
                <xsl:element name="address">
                    <xsl:value-of select="organisation/school/address"/>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:element name="teachers">
            <xsl:element name="wo_number">
                <xsl:value-of select="teachers/wo_number"/>
            </xsl:element>
            <xsl:element name="publication">
                <xsl:element name="date">
                    <xsl:value-of select="teachers/publication/date"/>
                </xsl:element>
                <xsl:element name="name">
                    <xsl:value-of select="teachers/publication/name"/>
                </xsl:element>
            </xsl:element>


        <xsl:for-each select="teachers/teacher">
            <xsl:choose>
                <xsl:when test=" starts-with(@id,'A2')">
                    <xsl:choose>
                        <xsl:when test="situation/ill='no'">
                            <xsl:element name="teacher">
                                <xsl:attribute name="id">
                                    <xsl:value-of select="@id"/>
                                </xsl:attribute>

                            <situation>
                                <xsl:element name="ill">
                                    <xsl:value-of select="situation[ill='no']"/>
                                </xsl:element>
                            </situation>
                            <situation>
                                <xsl:element name="ill">
                                    <xsl:value-of select="situation[ill='probable']"/>
                                </xsl:element>
                            </situation>
                            </xsl:element>
                        </xsl:when>

                        <xsl:when test="situation/ill='yes'"/>
                    </xsl:choose>   
                </xsl:when>
                <!--<xsl:when test=" starts-with(@id,'A2') and situation/ill='yes'"/>-->

                <xsl:when test="starts-with(@id,'G5')">
                    <xsl:choose>

                        <xsl:when test="situation/ill='no'">
                            <xsl:element name="teacher">
                                <xsl:attribute name="id">
                                    <xsl:value-of select="@id"/>
                                </xsl:attribute>

                                <situation>
                                    <xsl:element name="ill">
                                        <xsl:value-of select="situation[ill='no']"/>
                                    </xsl:element>
                                </situation>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="situation/ill='yes'">
                            <xsl:element name="teacher">
                                <xsl:attribute name="id">
                                    <xsl:value-of select="@id"/>
                                </xsl:attribute>

                                <situation>
                                    <xsl:element name="ill">
                                        <xsl:value-of select="situation[ill='yes']"/>
                                    </xsl:element>
                                </situation>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="situation/ill='probable'"/>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
        </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>