XSLT 更改 XML 元素顺序 [英] XSLT Change XML elements order
问题描述
我需要用我的转换重新排列源 XML 文件以获得:
I need to rearrange the source XML file with my transformation to obtain:
- 新的元素顺序.查看源和所需输出之间的差异:
应该出现在
和
内的元素之后也必须以不同的顺序出现. - 将源中不存在的元素添加为输出中的空元素 否则按原样复制元素(查看
元素)
- 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. - 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屋!