0

我使用这个 XML 源:

<?xml version="1.0" encoding="UTF-8"?>
<sets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="simulation-request.xsd">
<set>
    <hP />
    <para>
        <setP>
            <nom1>acc</nom1>
            <nom2></nom2>
            <typ>T</typ>
            <oP>T_EQUALS</oP>
            <val1>40</val1>
            <bId>21</bId>
        </setP>
    </para>
    <issuers />
</set>
<set>
    <hP>
        <sethP>
            <hTyp>EX</hTyp>             
            <tFt>L_D</tFt>
            <tFv>1</tFv>
            <sCF>cd</sCF>
            <setP>
                <nom1>bount</nom1>
                <oP>NLO</oP>
                <val1>00</val1>
                <bId>22</bId>
            </setP>
            <setP>
                <nom1>bount</nom1>
                <oP>NLO</oP>
                <val1>00</val1>
                <bId>23</bId>
            </setP>
            <setP>
                <nom1>bount</nom1>
                <oP>NLO</oP>
                <val1>00</val1>
                <bId>31</bId>
            </setP>

        </sethP>
    </hP>
    <para>
        <setP>
            <nom1>bount</nom1>
            <nom2></nom2>
            <typ>LO</typ>
            <oP>T_C</oP>
            <val1>1</val1>
            <bId>24</bId>
        </setP>
    </para>
    <issuers />
</set>  
</sets>

使用此 XSLT 源:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"   xml:space="preserve"/>
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/"><xsl:text>&#10;</xsl:text>   
    <xsl:for-each select="sets/set/hP | sets/set/para/setP">            
            <com-set-cond b.name="netInternalMs" name="{.//bId}">
            </com-set-cond><xsl:text>&#10;</xsl:text>
        </xsl:for-each>
</xsl:template>

输出如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<com-set-cond b.name="netInternalMs" name=""/>
<com-set-cond b.name="netInternalMs" name="21"/>
<com-set-cond b.name="netInternalMs" name="22"/>
<com-set-cond b.name="netInternalMs" name="24"/>

但预期的输出必须如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<com-set-cond b.name="netInternalMs" name="21"/>
<com-set-cond b.name="netInternalMs" name="22"/>
<com-set-cond b.name="netInternalMs" name="23"/>
<com-set-cond b.name="netInternalMs" name="31"/>
<com-set-cond b.name="netInternalMs" name="24"/>

其中 21、22、23、31 和 24 的每个数字是整个 xml 文件中元素bId的值,并且当祖先中没有bId元素时,如第一个标签,我的转换将不会显示任何内容,并且在使用我的转换后,输出文件中的第一行不会显示任何“名称”为空值的行有谁知道,该怎么做?谢谢你的帮助。

4

1 回答 1

0

问题在于您的xsl:for-each

<xsl:for-each select="sets/set/hP | sets/set/para/setP">   

特别是,sets/set/hP xpath。这将匹配两个hP元素。第一个是空的,因此生成了空名称属性。第二个包含三个setP元素,但是做name="{.//bId}"只会选择第一个(在这种情况下,bId = 22)

因此,您可能希望将您的xsl:for-each更改为此

<xsl:for-each select="sets/set/hP/sethP/setP | sets/set/para/setP"> 

如果您不担心setP元素出现的级别,可以将其简化为以下

<xsl:for-each select=".//setP">

请注意,通常首选使用xsl:apply-templates而不是xsl:for-each,因为这可以使代码更具可读性,减少缩进,并且更容易重用代码。

<xsl:template match="/">
    <xsl:text>&#10;</xsl:text>    
    <xsl:apply-templates select=".//setP" /> 
</xsl:template> 

<xsl:template match="setP">
   <com-set-cond b.name="netInternalMs" name="{.//bId}" />
   <xsl:text>&#10;</xsl:text>  
</xsl:template>
于 2012-07-29T11:44:42.867 回答