2

我有一个 XML 文件,我想从属性 = ruleId 的元素复制文本节点值(例如:CIAV819)并将其粘贴到属性 = ruleExpression 的下一个节点元素。下面是我要修改的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
        <Main>
            <installObj uniqueObjects="2822">
                <object class="Installer">
                    <visualChildren>
                        <object class="InstallSet">
                            <installchildrenMain>
                                <object class="com.zerog.ia.installer.InstallBundle1">
                                    <property name="ruleExpression">
                                        <string><![CDATA[]]></string>  ---paste1
                                    </property>
                                    <property name="bundleName">
                                        <string><![CDATA[Australia]]></string>
                                    </property>
                                    <rules logicalOperation="AND">
                                        <object class="CompareVariable">
                                            <property name="ruleId">
                                               <string><![CDATA[CIAV819]]></string> --copy1
                                            </property>
                                            <property name="operandOne">
                                               <string><![CDATA[$FEATURE$]]></string>
                                            </property>
                                        </object>
                                    </rules>
                                    <installChildren>
                                        <object class="com.zerog.ia.installer.InstallComponent1">
                                            <property name="ruleExpression">
                                                <string><![CDATA[]]></string>  --paste2
                                            </property>    
                                            <property name="componentName">
                                                <string><![CDATA[AUST]]></string>
                                            </property>
                                            <rules logicalOperation="AND">
                                                <object class="CompareVariable">
                                                    <property name="ruleId">
                                                        <string><![CDATA[CIAV962]]></string> --copy2.1
                                                    </property>
                                                    <property name="operandOne">
                                                 <string><![CDATA[$FEATURE$]]></string>
                                           </property>
                                                 </object>
                                                 <object class="CompareVariable">
                                 <property name="ruleId">
                                    <string><![CDATA[CIAV503]]></string> --copy2.2
                  </property>
                                                 </object>
                                                </rules>
                                            <installChildren>
                                                <object class="com.zerog.ia.installer.InstallDirCont">
                                                    <property name="ruleExpression">
                                                        <string><![CDATA[]]></string>  --paste3
                                                    </property>
                                                    <property name="operandOne">
                                                 <string><![CDATA[$FEATURE$]]></string>
                                         </property>
                                                    <rules logicalOperation="OR">
                                                        <object class="CompareVariable1">
                                                            <property name="ruleId">
                                                                <string><![CDATA[CIAV100]]></string> --COPY3.1 </property>
                                                            <property name="operandOne">
                                                        <string><![CDATA[$FEATURE$]]></string>  </property>

                                                        </object>
                                                        <object class="CompareVariable2">
                                                            <property name="ruleId">
                                                                <string><![CDATA[CIAV200]]></string><!-- COPY3.2 -->
                                                            </property>
                                                            <property name="operandOne">
                                                       <string><![CDATA[$FEATURE$]]></string>
                                                </property>

                                                        </object>
                                                    </rules>
                                                </object>
                                            </installChildren>
                                        </object><!-- end of installComponent1 -->
                                        <object class="com.zerog.ia.installer.InstallComponent2" >
                                            <!--
                                            Same as above (Install Component1)
                                            -->
                                        </object><!-- end of installComponent2 -->
                                    </installChildren>   
                                </object><!-- end of installBundle1 -->

                                <object class="com.zerog.ia.installer.InstallBundle2" >
                                    <property name="ruleExpression">
                                        <string><![CDATA[]]></string>  ---paste4
                                    </property>
                                    <property name="bundleName">
                                        <string><![CDATA[** ** Database]]></string>
                                    </property>
                                    <rules logicalOperation="AND">
                                        <object class="CompareVariable">
                                            <property name="ruleId">
                                               <string><![CDATA[CIAV111]]></string> --copy4
                                            </property>
                                            <property name="operandOne">
                                               <string><![CDATA[something]]></string>
                                            </property>
                                        </object>
                                    </rules>
                                    <installChildren>
                                        <object class="com.zerog.ia.installer.InstallComponent1">
                                            <property name="ruleExpression">
                                                <string><![CDATA[]]></string>  --paste5
                                            </property>    
                                            <property name="componentName">
                        <string><![CDATA[Common]]></string>
                            </property>
                                            <rules logicalOperation="AND">
                                                <object class="CompareVariable">
                                                    <property name="ruleId">
                                                        <string><![CDATA[]]></string> --copy5.1 
</property>
                                                    <property name="operandOne">
                                                 <string><![CDATA[$FEATURE$]]></string>
                                           </property>
                                                 </object>
                                                 <object class="CompareVariable">
                                               <property name="ruleId">
                                    <string><![CDATA[]]></string> --copy5.2
                  </property>
                                                 </object>
                                                </rules>
                                </object><!-- end of installBundle2 -->
                            </installchildrenMain>
                        </object><!-- end of InstallSet -->
                    </visualChildren><!-- end of visualChildren -->
                </object><!-- end of Installer -->
            </installObj>
            <restorationObjects count="0"/>
        </Main>

将“CIAV819”值从 copy1 位置复制到 paste1 位置,对于其他 copy2 和 copy3 位置也是如此。其中例如 paste1 位置应如下所示:

<property name="ruleExpression">
   <string><![CDATA[CIAV819]]></string>  ---paste1
</property>

paste2 位置应如下所示:

<property name="ruleExpression">
   <string><![CDATA[CIAV962 && CIAV503]]></string>  ---paste2
</property>

paste3 位置应如下所示:

<property name="ruleExpression">
   <string><![CDATA[CIAV100 || CIAV200]]></string>  ---paste3
</property>

但只有 paste5 文本节点应保持空白,因为 copy5.1 和 copy5.2 文本节点为空。即下<object class="InstallBundle2" >当它

<property name="bundleName">
   <string><![CDATA[** ** Database]]></string>
 </property>

它的其中一个 InstallComponent 在 this 下具有

<property name="componentName">
    <string><![CDATA[Common]]></string>
</property>

应该像这样将 paste5 设为空:

<property name="ruleExpression">
       <string><![CDATA[]]></string>  ---paste5
    </property>

我正在使用以下 XSLT 转换来获取我的输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output cdata-section-elements="string" />

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

<xsl:template match="object[starts-with(@class, 'com.zerog.ia.installer.Install')]/property[@name='ruleExpression']">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <string>
            <xsl:apply-templates select="following-sibling::rules[1]" mode="copy" />
         </string>
    </xsl:copy>
</xsl:template>

<xsl:template match="object[starts-with(@class, 'com.zerog.ia.installer.actions.InstallDirCont')]/property[@name='ruleExpression']">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <string>
            <xsl:apply-templates select="following-sibling::rules[1]" mode="copy" />
         </string>
    </xsl:copy>
</xsl:template>

<xsl:template match="rules" mode="copy">
    <xsl:variable name="operator">
       <xsl:choose>
          <xsl:when test="@logicalOperation='OR'"> || </xsl:when>
          <xsl:otherwise> &amp;&amp; </xsl:otherwise>
       </xsl:choose>
    </xsl:variable>
    <xsl:for-each select="object/property[@name='ruleId']/string">
        <xsl:if test="position() > 1"><xsl:value-of select="$operator" /></xsl:if>
        <xsl:value-of select="." />
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

我在我的 PHP 文件(如下所示)中运行这个 XSLT,它正在处理这个 xml/xslt 文件:

<?php
$xmldoc = new DOMDocument();
$xmldoc->load('ELS92.iap_xml');

$xsldoc = new DOMDocument();
$xsldoc->load('transform.xslt');

$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsldoc);

$result = $xslt->transformToDoc($xmldoc);
$result->save($xmldoc);
?>

运行此 XSLT 后,我的 paste5 如下所示:

<property name="ruleExpression">
 <string><![CDATA[ && ]]>
</string>
</property>

这是不对的!

另外我该如何调试我的xslt?我可以将 xslt 处理输出到某个文本文件吗?因为有时我的完整 xml 变为空白可能是因为它找不到某些所需的模板?

谢谢

4

1 回答 1

2

对于您的“粘贴 5”,您正在执行for-each两个节点,这两个节点都具有空字符串属性值,因此它正确地执行空字符串 + " && "+ 空字符串。您需要做的是过滤您正在处理的节点列表,以便该列表仅包含非空节点:

<xsl:template match="rules" mode="copy">
    <xsl:variable name="operator">
       <xsl:choose>
          <xsl:when test="@logicalOperation='OR'"> || </xsl:when>
          <xsl:otherwise> &amp;&amp; </xsl:otherwise>
       </xsl:choose>
    </xsl:variable>
    <xsl:for-each select="object/property[@name='ruleId']/string[normalize-space()]">
        <xsl:if test="position() > 1"><xsl:value-of select="$operator" /></xsl:if>
        <xsl:value-of select="." />
    </xsl:for-each>
</xsl:template>

谓词string表示,在情况 5 中,这将选择节点而不是两个 (normalize-space()为您提供删除前导和尾随空格的节点的值,并且连续空白字符的所有内部运行折叠到单个空格 - 这将是空字符串如果该值为空或仅包含空格,并且当用作谓词时,空字符串表示“假”)。

于 2013-11-15T11:34:24.437 回答