XSLT 更改 XML 元素顺序 [英] XSLT Change XML elements order

查看:47
本文介绍了XSLT 更改 XML 元素顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要用我的转换重新排列源 XML 文件以获得:

I need to rearrange the source XML file with my transformation to obtain:

  1. 新的元素顺序.查看源和所需输出之间的差异: 应该出现在 内的元素之后也必须以不同的顺序出现.
  2. 将源中不存在的元素添加为输出中的空元素 否则按原样复制元素(查看
    元素)
  1. A new elements order. Look the difference between source and desired output: <gmd:role> should appear AFTER <contactInfo> and elements inside <CI_Contact> have to appear in different order too.
  2. Add elements that are not present in the source as empty elements in the output otherwise copy the element as-is (look at the <address> element)

源文件:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="c:\ISO19139_rve.xsl"?>
<MD_Metadata xmlns="http://www.isotc211.org/schemas/2005/gmd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/schemas/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.isotc211.org/schemas/2005/gmd/gmd.xsd">
<CI_ResponsibleParty>
    <organizationName>
        <gco:CharacterString>Organisation Name</gco:CharacterString>
    </organizationName>
    <role>
        <CI_RoleCode codeList="./resource/codeList.xml#CI_RoleCode" codeListValue="Proprietario">Proprietario</CI_RoleCode>
    </role>
    <contactInfo>
        <CI_Contact>
            <onlineResource>
                <CI_OnlineResource>
                    <linkage>
                        <URL>http://www.mydomain.it</URL>
                    </linkage>
                </CI_OnlineResource>
            </onlineResource>
            <phone>
                <CI_Telephone>
                    <voice>
                        <gco:CharacterString>+39 123 456789</gco:CharacterString>
                    </voice>
                </CI_Telephone>
            </phone>
        </CI_Contact>
    </contactInfo>
</CI_ResponsibleParty>
</MD_Metadata>

预期结果:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="c:\ISO19139_rve.xsl"?>
<MD_Metadata xmlns="http://www.isotc211.org/schemas/2005/gmd"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:gco="http://www.isotc211.org/schemas/2005/gco"
             xmlns:gml="http://www.opengis.net/gml"
             xmlns:xlink="http://www.w3.org/1999/xlink"
             xsi:schemaLocation="http://www.isotc211.org/schemas/2005/gmd/gmd.xsd">
<gmd:CI_ResponsibleParty>
  <gmd:organisationName>
    <gco:CharacterString>Organisation Name</gco:CharacterString>
  </gmd:organisationName>
  <gmd:contactInfo>
    <gmd:CI_Contact>
      <gmd:phone>
        <gmd:CI_Telephone>
          <gmd:voice>
            <gco:CharacterString>+39 123 456789</gco:CharacterString>
          </gmd:voice>
        </gmd:CI_Telephone>
      </gmd:phone>
      <gmd:address>
        <gmd:CI_Address>
          <gmd:electronicMailAddress>
            <gco:CharacterString/>
          </gmd:electronicMailAddress>
        </gmd:CI_Address>
      </gmd:address>
      <gmd:onlineResource>
        <gmd:CI_OnlineResource>
          <gmd:linkage>
            <gmd:URL>http://www.mydomain.it</gmd:URL>
          </gmd:linkage>
        </gmd:CI_OnlineResource>
      </gmd:onlineResource>
    </gmd:CI_Contact>
  </gmd:contactInfo>
  <gmd:role>
    <gmd:CI_RoleCode codeList="./resource/codeList.xml#CI_RoleCode" codeListValue="owner">Proprietario</gmd:CI_RoleCode>
  </gmd:role>
</gmd:CI_ResponsibleParty>
</MD_Metadata>

我的转变:

<xsl:stylesheet
    version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:gco="http://www.isotc211.org/schemas/2005/gco"
    xmlns:gmd="http://www.isotc211.org/schemas/2005/gmd"
    xmlns="http://www.isotc211.org/schemas/2005/gmd"
    >

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

    <xsl:output indent="yes" encoding="UTF-8"/>

    <!-- identity template -->
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="gmd:CI_ResponsibleParty" exclude-result-prefixes="#all">
        <xsl:copy>
            <!--<xsl:copy-of select="@*" />-->
            <xsl:copy-of select="gmd:organizationName" />
            <xsl:apply-templates select="gmd:contactInfo" />
            <xsl:copy-of select="gmd:role" />
            <!--<xsl:apply-templates select="node()" />-->
        </xsl:copy>
    </xsl:template>

    <!--<xsl:template match="gmd:contactInfo" />-->

    <xsl:template match="gmd:contactInfo" exclude-result-prefixes="#all">
        <xsl:copy>
            <xsl:copy-of select="gmd:phone" />
            <xsl:apply-templates select="gmd:address" />
            <xsl:if test="not(gmd:address)">
                <address>
                    <CI_Address>
                        <electronicMailAddress>
                            <gco:CharacterString/>
                        </electronicMailAddress>
                    </CI_Address>
                </address>
            </xsl:if>
            <xsl:copy-of select="gmd:onlineResource" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

推荐答案

我认为你想使用 <xsl:template match="gmd:CI_contact">,而不是 <xsl:template match="gmd:contactInfo">

I think you want to use <xsl:template match="gmd:CI_contact">, not <xsl:template match="gmd:contactInfo">

<xsl:template match="gmd:CI_Contact">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:apply-templates select="gmd:phone" />
        <xsl:apply-templates select="gmd:address" />
        <xsl:if test="not(gmd:address)">
            <address>
                <CI_Address>
                    <electronicMailAddress>
                        <gco:CharacterString/>
                    </electronicMailAddress>
                </CI_Address>
            </address>
        </xsl:if>
        <xsl:apply-templates select="gmd:onlineResource" />
    </xsl:copy>
</xsl:template>

作为一个好习惯:在基于身份模板的样式表中,更喜欢 而不是 .

As a good practice: In stylesheets that are based on the identity template, prefer <xsl:apply-templates> over <xsl:copy>.

最终效果将相同(输入将被复制),但这样您就可以轻松附加另一个处理特殊情况的模板,而不必接触现有模板.

The end effect will be the same (the input will be copied) but this way you keep it easy to append another template that handles a special case while not having to touch the existing templates.

假设:假设您想在任何地方删除所有 @foo 属性.因为上面使用了<xsl:apply-templates select="@*">,所以是追加的问题

Hypothetically: Say you want to drop all @foo attributes everywhere. Because the above uses <xsl:apply-templates select="@*">, it's a matter of appending

<xsl:template match="@foo" />

但是,如果您使用 <xsl:copy-of select="@*"/> 您必须更改这一行以及可能有 @foo 的其他十几个地方 将被复制.

However if you use <xsl:copy-of select="@*" /> you'd have to change this line and probably a dozen other places where @foo would be copied.

这篇关于XSLT 更改 XML 元素顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆