我有一个大致如下所示的 XML 文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Multiple xmlns:ns2="someNs2" xmlns="someGenericNs" xmlns:ns4="someNs4" xmlns:ns3="someNs3">
<Single>
<Id>60000</Id>
<Type>Activate</Type>
<Payload>
<ns3:Activation>
<ns3:Parent>
<ns3:TypeId>113</ns3:TypeId>
<ns3:TypeName>TestApplication</ns3:TypeName>
</ns3:Parent>
<ns3:Children>
<ns3:Child>
<ns3:Key>someKey</ns3:Key>
<ns3:ChildTypeName>BadAppType1</ns3:ChildTypeName>
</ns3:Child>
<ns3:Child>
<ns3:Key>someOtherKey</ns3:Key>
<ns3:ChildTypeName>GoodAppType1</ns3:ChildTypeName>
</ns3:Child>
</ns3:Children>
</ns3:Activation>
</Payload>
</Single>
</Multiple>
我需要做的是将其转换为更简单的形式,例如:
<?xml version="1.0" encoding="UTF-8"?>
<MyNewRootNode xmlns="MyNewNamespace">
<Activation>
<ApplicationType>TestApplication</ApplicationType>
<ValidChildTypeName>GoodAppType1</ValidChildTypeName>
<ValidChildKey>someOtherKey</ValidChildKey>
</Activation>
</MyNewRootNode>
初始 XML 可以包含多个子节点,其中只有一个具有有效的“CildTypeName”节点。我的问题是,如果 XML 确实包含多个子节点,那么我的 XSLT 将只抓取第一个并将其转换为新格式,即使它包含无效的“ChildTypeName”。
总结一下:我需要将我的 XML 转换为更简单的形式。要创建这个更简单的表单,我需要过滤所有“Child”节点并找到包含有效“ChildTypeName”的节点,并将其“Key”和“ChildTypeName”的值复制到新的 XML。
我还有一个预定义的有效“ChildTypeNames”列表。它包含大约 3 个名称,并且不会很快改变。
这是我到目前为止所使用的 XSLT:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="MyNewNamespace" xmlns:ns3="someNs3" exclude-result-prefixes="ns3">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="activationNode">
<xsl:text>Activation</xsl:text>
</xsl:variable>
<xsl:variable name="new-root-node">
<xsl:text>MyNewRootNode</xsl:text>
</xsl:variable>
<xsl:template match="/*">
<xsl:element name="{$new-root-node}">
<xsl:element name="{$activationNode}">
<xsl:call-template name="TemplateOne"/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="TemplateOne">
<xsl:element name="ApplicationType">
<xsl:value-of select="//ns3:Activation/ns3:Parent/ns3:TypeName"/>
</xsl:element>
<xsl:element name="ValidChildTypeName">
<xsl:value-of select="//ns3:Activation/ns3:Children/ns3:Child/ns3:ChildTypeName"/>
</xsl:element>
<xsl:element name="ValidChildKey">
<xsl:value-of select="//ns3:Activation/ns3:Children/ns3:Child/ns3:Key"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但这将抓取它找到的第一个子节点,在本例中是带有“BadAppType1”的子节点。
更新:在这方面取得了一些进展。将 XSLT 的最后一部分更改为:
<xsl:for-each select="//ns3:Activation/ns3:Children/ns3:Child">
<xsl:if test="ns3:ChildTypeName[text()='GoodAppType1']">
<xsl:element name="ValidChildTypeName">
<xsl:value-of select="ns3:ChildTypeName"/>
</xsl:element>
<xsl:element name="ValidChildKey">
<xsl:value-of select="ns3:Key"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
据我所知,我只需要一种方法来检查多个可能的有效值,它应该是正确的。