![](/img/trans.png)
[英]Is it possible to group child nodes based on element name in xslt 1.0?
[英]XSLT: I am trying to flatten XML element based on child element name using XSLT 1.0
我试图使用XSLT 1.0基于子元素名称展平XML元素
源XML:
<Contact>
<ContactPurpose>
<PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText>
</ContactPurpose>
<ContactPurpose>
<PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum>
</ContactPurpose>
</Contact>
应该转换成以下XML:
<Contact>
<ContactPurpose>O</ContactPurpose>
<ContactPurpose>Call</ContactPurpose>
</Contact>
逻辑是:
如果子元素名称是“PurposeAsPlainText”那么为目的地中的其他设置“O”
ELSEIF子元素名称是“PurposeAsEnum”然后将源值复制到目标
编辑1 :我可以更清楚,因为没有任何解决方案压扁xml,请参阅修订的源和目标XML。
编辑2 :这是我正在测试的XML。 下面的两个转换解决方案实际上对我的原始xml有效,但不是我使用.NET 4.0 XslCompiledTransform测试的修改后的xml。 或者我应该提出一个新问题?
<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PatientRecord>
<Demographics>
<Contact>
<ContactPurpose>
<PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText>
</ContactPurpose>
<ContactPurpose>
<PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum>
</ContactPurpose>
</Contact>
</Demographics>
</PatientRecord>
</MyDS>
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cds="cds_dt" exclude-result-prefixes="cds">
<!-- identity transform - just copy things that don't have a better rule -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!- a rule for what needs changing -->
<xsl:template match="ContactPurpose[cds:PurposeAsPlainText] ">
<ContactPurpose>O</ContactPurpose>
</xsl:template>
</xsl:stylesheet>
更新:修改了答案以适应更改的XML源文档。
描述不是很清楚,但这是我认为你要做的事情:
<xsl:stylesheet version="1.0" xmlns:cds_dt="cds_dt" xmlns:cds="cds"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="cds:ContactPurpose">
<xsl:copy>
<xsl:choose>
<!-- when there is a child element PurposeAsPlainText
in the cds_dt namespace: -->
<xsl:when test="cds_dt:PurposeAsPlainText">0</xsl:when>
<!-- I'm guessing that PurposeAsEnum is also supposed to be
in the cds_dt namespace. -->
<xsl:otherwise>
<xsl:value-of select="cds_dt:PurposeAsEnum" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这可以通过简单而简短的方式完成(没有明确的条件) :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="cds_dt" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template>
<xsl:template match="ContactPurpose/*"><xsl:apply-templates/></xsl:template>
</xsl:stylesheet>
当应用于以下XML文档时 (扩展为包含两个感兴趣的案例):
<Contact>
<ContactPurpose>
<PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText>
</ContactPurpose>
<ContactPurpose>
<PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum>
</ContactPurpose>
</Contact>
产生想要的,正确的结果 :
<Contact>
<ContactPurpose>0</ContactPurpose>
<ContactPurpose>Call</ContactPurpose>
</Contact>
说明 :
覆盖标识规则并适当使用模板/匹配模式。
更新 :OP修改了他的XML文档,该文档现在位于默认命名空间中:
<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PatientRecord>
<Demographics>
<Contact>
<ContactPurpose>
<PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText>
</ContactPurpose>
<ContactPurpose>
<PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum>
</ContactPurpose>
</Contact>
</Demographics>
</PatientRecord>
</MyDS>
因此,这是一个略微修改的转换,产生想要的结果 :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="cds_dt" xmlns:c="cds" exclude-result-prefixes="c x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c:ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template>
<xsl:template match="c:ContactPurpose/*"><xsl:apply-templates/></xsl:template>
</xsl:stylesheet>
当此转换应用于新的XML文档(上面最近的)时,会生成新的想要的正确结果 :
<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PatientRecord>
<Demographics>
<Contact>
<ContactPurpose>0</ContactPurpose>
<ContactPurpose>Call</ContactPurpose>
</Contact>
</Demographics>
</PatientRecord>
</MyDS>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.