У меня есть файл XML, который выглядит примерно так:XSL элементы Отвернуть на основе условий
<?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 в более простой форме. Чтобы создать эту более простую форму, мне нужно отфильтровать все «дочерние» узлы и найти тот, который содержит , действительный «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>
Насколько я могу сказать, мне нужно только способ проверить более одного возможного допустимого значения, и он должен быть правильным.