XSLT:value-of返回重复元素值

时间:2018-04-03 20:22:06

标签: xml xslt xsd value-of

我正在尝试提取与特定值的属性相关联的元素值:示例://个人资料/主题/ Attrib [@name ='说明'] 返回的值在每个配置文件的输出XML中重复。 目标实体是" Profile"其中应包含姓名,订单,状态,订单说明,关键字和关键字说明。

XML来源:

 <?xml version="1.0" encoding="UTF-8"?>
<CustomerExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file://xxxTestApr3.xsd">
    <Customer id="" name="165368 - XXXX - XXXX (I)">
        <Attrib name="description"/>
        <Profile agent="0" autodist="0" billing_day="19" changedate="" customerfiltername="Priority" mail="" name="165368 - XXXX - XXXX" neuronal="0" orderid="165368" show_on_portal="0" status="I" topnews="0" type="query" validfrom="" validfromsource="" validto="" validtosource="">
            <Attrib name="description">IF AN ARTICLE IS GOOD FOR 165368 AND 165391, ONLY MARK FOR 165368 ICW CANADA</Attrib>
            <ProfileXML public="-//XXXX//DTD Profile 2.0//EN" system="profile_2_0.dtd">
                <Profile>
                    <Topic>
                        <Attrib name="name">KEYWORDS</Attrib>
                        <Attrib name="weight">60</Attrib>
                        <Attrib name="description">RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN</Attrib>
                        <Term>
                            <Attrib name="name">CARDINAL VILLENEUVE</Attrib>
                            <Attrib name="fuzzy">0</Attrib>
                            <Attrib name="morphology">0</Attrib>
                            <Attrib name="exact">0</Attrib>
                            <Attrib name="description">ICW CENTRE CARDINAL-VILLENEUVE</Attrib>
                        </Term>
                    </Topic>
                </Profile>
            </ProfileXML>
        </Profile>
    </Customer>
    <Customer id="" name="010 - TEST">
        <Attrib name="description"/>
        <Profile agent="0" autodist="0" billing_day="20" changedate="" customerfiltername="" mail="" name="010 - TEST" neuronal="0" orderid="10" show_on_portal="0" status="I" topnews="0" type="query" validfrom="" validfromsource="" validto="" validtosource="">
            <Attrib name="description"/>
            <ProfileXML public="-//XXXXX//DTD Profile 2.0//EN" system="profile_2_0.dtd">
                <Profile>
                    <Topic>
                        <Attrib name="name">KEYWORDS</Attrib>
                        <Attrib name="weight">60</Attrib>
                        <Term>
                            <Attrib name="name">Benjamin Franklin</Attrib>
                            <Attrib name="fuzzy">0</Attrib>
                            <Attrib name="morphology">0</Attrib>
                            <Attrib name="exact">0</Attrib>
                            <Attrib name="description">For testing only</Attrib>
                        </Term>
                    </Topic>
                </Profile>
            </ProfileXML>
        </Profile>
    </Customer>
    <Customer id="" name="165370 - XXXX - XXXXXA XXXXXC (I)">
        <Attrib name="description"/>
        <Profile agent="0" autodist="0" billing_day="10" changedate="" customerfiltername="" mail="" name="165370 - XXXX - XXXXXA XXXXXC" neuronal="0" orderid="165370" show_on_portal="0" status="I" topnews="0" type="query" validfrom="" validfromsource="" validto="" validtosource="">
            <Attrib name="description"/>
            <ProfileXML public="-//XXXXX//DTD Profile 2.0//EN" system="profile_2_0.dtd">
                <Profile>
                    <Topic>
                        <Attrib name="name">KEYWORDS</Attrib>
                        <Attrib name="weight">60</Attrib>
                        <Attrib name="description">OMIT MERE MENTIONS</Attrib>
                        <Term>
                            <Attrib name="name">KEEPHILLS</Attrib>
                            <Attrib name="fuzzy">0</Attrib>
                            <Attrib name="morphology">0</Attrib>
                            <Attrib name="exact">0</Attrib>
                            <Attrib name="description">ICW KEEPHILLS POWER PLANT
OR ICW POWER GENERATION AT KEEPHILLS PLANT</Attrib>
                        </Term>
                        <Term>
                            <Attrib name="name">SUN 7 PLANT</Attrib>
                            <Attrib name="fuzzy">0</Attrib>
                            <Attrib name="morphology">0</Attrib>
                            <Attrib name="exact">0</Attrib>
                            <Attrib name="description">ICW SUNDANCE GAS FIRED POWER PLANT
OR ICW SUNDANCE COAL FIRED POWER PLANT
OR ICW ELECTRICAL POWER GENERATION AT SUNDANCE PLANT
OMIT SUNDANCE FILM FESTIVAL</Attrib>
                        </Term>
                    </Topic>
                </Profile>
            </ProfileXML>
        </Profile>
    </Customer>
</CustomerExport>

XSD:

    <?xml version="1.0" encoding="UTF-8"?>
<!-- W3C Schema generated by XMLSpy v2018 sp1 (http://www.altova.com) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Term">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Attrib" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Rules">
        <xs:complexType/>
    </xs:element>
    <xs:element name="Topic">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Attrib" maxOccurs="unbounded"/>
                <xs:element ref="Term" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Attrib">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="name" use="required">
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:enumeration value="description"/>
                                <xs:enumeration value="exact"/>
                                <xs:enumeration value="fuzzy"/>
                                <xs:enumeration value="morphology"/>
                                <xs:enumeration value="name"/>
                                <xs:enumeration value="weight"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>
    <xs:element name="Profile">
        <xs:complexType>
            <xs:choice>
                <xs:sequence>
                    <xs:element ref="Attrib"/>
                    <xs:element ref="ProfileXML"/>
                    <xs:element ref="MediaFilter"/>
                </xs:sequence>
                <xs:element ref="Topic"/>
            </xs:choice>
            <xs:attribute name="agent">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="autodist">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="billing_day">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="10"/>
                        <xs:enumeration value="19"/>
                        <xs:enumeration value="20"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="changedate">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="customerfiltername">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                        <xs:enumeration value="Priority"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="mail">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="name">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="010 - TEST"/>
                        <xs:enumeration value="165368 - XXX - XXXX"/>
                        <xs:enumeration value="165370 - XXXXXA - XXXXX XXXXX"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="neuronal">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="orderid">
                <xs:simpleType>
                    <xs:restriction base="xs:int">
                        <xs:enumeration value="10"/>
                        <xs:enumeration value="165368"/>
                        <xs:enumeration value="165370"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="show_on_portal">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="status">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="I"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="topnews">
                <xs:simpleType>
                    <xs:restriction base="xs:byte">
                        <xs:enumeration value="0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="type">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="query"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="validfrom">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="validfromsource">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="validto">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="validtosource">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="Customer">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Attrib"/>
                <xs:element ref="Profile"/>
            </xs:sequence>
            <xs:attribute name="id" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value=""/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="name" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="010 - TEST"/>
                        <xs:enumeration value="165368 - XXX - XXXX"/>
                        <xs:enumeration value="165370 - XXXXXA - XXXXX XXXXX"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="PubGroup">
        <xs:complexType>
            <xs:attribute name="include" type="xs:boolean" use="required"/>
            <xs:attribute name="name" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="All Canada"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="PubGroups">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="PubGroup" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="ProfileXML">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Profile"/>
            </xs:sequence>
            <xs:attribute name="public" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="-//XXXXXX XXX//DTD Profile 2.0//EN"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="system" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="profile_2_0.dtd"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="CustomerExport">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Customer" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <NB xsi:noNamespaceSchemaLocation="TestApr3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <xsl:for-each select="/CustomerExport/Customer/Profile">
                <Profile>
                    <PName>
                        <xsl:value-of select="@name"/>
                    </PName>
                    <OrderID>
                        <xsl:value-of select="@orderid"/>
                    </OrderID>
                    <Status>
                        <xsl:value-of select="@status"/>
                    </Status>   
                    <OrderInst>
                        <xsl:value-of select="Attrib"/>
                    </OrderInst>
                    <TopicInst>
                        <xsl:value-of select="//Topic/Attrib[@name='description']"/>
                    </TopicInst>
                </Profile>
            </xsl:for-each>
        </NB>
    </xsl:template>
</xsl:stylesheet>

XSL输出

 <?xml version="1.0" encoding="UTF-8"?>
<NB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TestApr3.xsd">
    <Profile>
        <PName>165368 - XXXX - XXXX</PName>
        <OrderID>165368</OrderID>
        <Status>I</Status>
        <OrderInst>IF AN ARTICLE IS GOOD FOR 165368 AND 165391, ONLY MARK FOR 165368 ICW CANADA</OrderInst>
        <TopicInst>RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN</TopicInst>
    </Profile>
    <Profile>
        <PName>010 - TEST</PName>
        <OrderID>10</OrderID>
        <Status>I</Status>
        <OrderInst/>
        <TopicInst>RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN</TopicInst>
    </Profile>
    <Profile>
        <PName>165370 - XXXX - XXXXXA XXXXXC</PName>
        <OrderID>165370</OrderID>
        <Status>I</Status>
        <OrderInst/>
        <TopicInst>RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN</TopicInst>
    </Profile>
</NB>

输出元素&#34; TopicInst&#34;包含来自集合中第一个配置文件的XML源的重复元素值(配置文件名称的第12行 - &#34; 165368 - XXXX - XXXX&#34;)

我已经使用XPath测试了上下文节点,并且我能够从&#34; Attrib&#34;中获取两个元素值。 @name =&#39; description&#39; //主题/ Attrib [@name =&#39; description&#39;] ..但是,我可以在xslt中完成这项工作

Attrib  RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN
Attrib  OMIT MERE MENTIONS

我已经尝试过xsl:if,for-each的值为,没有运气。 非常感谢任何建议。

1 个答案:

答案 0 :(得分:2)

尝试在XPath表达式前添加<xsl:value-of select=".//Topic/Attrib[@name='description']"/> ,例如

  <Profile>
    ...
    <TopicInst>RIEN SUR FONDATION ÉLAN / NOTHING ON FONDATION ÉLAN</TopicInst>
  ...
  <Profile>
    ...
    <TopicInst/>
  ...
  <Profile>
    ...
    <TopicInst>OMIT MERE MENTIONS</TopicInst>

这使得查找从当前节点开始 如果那是你想要的,那么输出就变成了以下内容。

helloworld.pyx