为什么()在我的xslt中不起作用?

时间:2013-06-20 09:04:01

标签: xml xslt xsd

嗨首先请原谅我的英语; D

我遇到以下问题:

XML

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

<HYDRO_P xmlns="http://www.hydro.ch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.hydro.ch test.xsd">

<!-- groups on project -->

<scada>

    <logicalDevice name="MTU">

        <logicalNode type="specific" name="t_1">  
            <datatype type="messurement" name="speed of PLC1" ref="ID-01" priority="7"/> 
        </logicalNode>


    </logicalDevice>


</scada>

<!-- connected fields on Project -->

<field>

<agent id="100" name="AGENT1" driver="Modbus Serial" port="Serial" portnb="5">
    <device id="101" name="DEVICE1" devicetype="Modbus RTU: M340">
        <address>
            <modbus address="5"/>
            <ip address="127.0.0.1"/>
        </address>
        <items>

            <collection name="COLLECTION1">
                <item id="ID-02" name="ITEM2" datatype="Word" rights="Read/Write">
                    <description>aaaaa</description>
                    <address>IW248</address>
                </item>
            </collection>

            <item id="ID-01" name="ITEM1" datatype="Byte" rights="Read Only">
                <description>BBaa</description>
                <address>IB02</address>
            </item>


        </items>
    </device>
</agent>

</field>


</HYDRO_P>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.hydro.ch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="http://www.hydro.ch">
<xs:import namespace="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="xsi.xsd"/>
<xs:element name="HYDRO_P">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:scada"/>
      <xs:element ref="ns1:field"/>
    </xs:sequence>
    <xs:attribute ref="xsi:schemaLocation" use="required"/>
  </xs:complexType>
</xs:element>
<xs:element name="scada">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:logicalDevice"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="logicalDevice">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:logicalNode"/>
    </xs:sequence>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
  </xs:complexType>
</xs:element>
<xs:element name="logicalNode">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:datatype"/>
    </xs:sequence>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
    <xs:attribute name="type" use="required" type="xs:NCName"/>
  </xs:complexType>
</xs:element>
<xs:element name="datatype">
  <xs:complexType>
    <xs:attribute name="name" use="required"/>
    <xs:attribute name="priority" use="required" type="xs:integer"/>
    <xs:attribute name="ref" use="required" type="xs:IDREF"/>
    <xs:attribute name="type" use="required" type="xs:NCName"/>
  </xs:complexType>
</xs:element>
<xs:element name="field">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:agent"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="agent">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:device"/>
    </xs:sequence>
    <xs:attribute name="driver" use="required"/>
    <xs:attribute name="id" use="required" type="xs:integer"/>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
    <xs:attribute name="port" use="required" type="xs:NCName"/>
    <xs:attribute name="portnb" use="required" type="xs:integer"/>
  </xs:complexType>
</xs:element>
<xs:element name="device">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:address"/>
      <xs:element ref="ns1:items"/>
    </xs:sequence>
    <xs:attribute name="devicetype" use="required"/>
    <xs:attribute name="id" use="required" type="xs:integer"/>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
  </xs:complexType>
</xs:element>
<xs:element name="items">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:collection"/>
      <xs:element ref="ns1:item"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="collection">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:item"/>
    </xs:sequence>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
  </xs:complexType>
</xs:element>
<xs:element name="address">
  <xs:complexType mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="ns1:ip"/>
      <xs:element ref="ns1:modbus"/>
    </xs:choice>
  </xs:complexType>
</xs:element>
<xs:element name="ip">
  <xs:complexType>
    <xs:attribute name="address" use="required" type="xs:NMTOKEN"/>
  </xs:complexType>
</xs:element>
<xs:element name="modbus">
  <xs:complexType>
    <xs:attribute name="address" use="required" type="xs:integer"/>
  </xs:complexType>
</xs:element>
<xs:element name="item">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="ns1:description"/>
      <xs:element ref="ns1:address"/>
    </xs:sequence>
    <xs:attribute name="datatype" use="required" type="xs:NCName"/>
    <xs:attribute name="id" use="required" type="xs:ID"/>
    <xs:attribute name="name" use="required" type="xs:NCName"/>
    <xs:attribute name="rights" use="required"/>
  </xs:complexType>
</xs:element>
<xs:element name="description" type="xs:NCName"/>
</xs:schema>

我想用xslt:

得到类似的东西

PLC1的MTU.t_1.speed,$ [MTU] .AGENT1.DEVICE1.ITEM1 ...

我尝试过类似的东西: XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fr="http://www.hydro.ch"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    version="2.0">
 <xsl:output method="text" indent="no"/>


    <xsl:template match="/">
        <xsl:apply-templates select="fr:HYDRO_P"/>
    </xsl:template>



 <xsl:template match="fr:HYDRO_P">

     <xsl:value-of select="fr:scada/fr:logicalDevice/@name"/>.
     <xsl:value-of select="fr:scada/fr:logicalDevice/fr:logicalNode/@name"/>.
     <xsl:value-of select="fr:scada/fr:logicalDevice/fr:logicalNode/fr:datatype/@name"/>,
     $[<xsl:value-of select="fr:scada/fr:logicalDevice/@name"/>].
     <xsl:value-of select="fr:scada/fr:logicalDevice/fr:logicalNode/fr:datatype/id(@ref)/ancestor::agent/@name"/>.
     <xsl:value-of select="fr:scada/fr:logicalDevice/fr:logicalNode/fr:datatype/id(@ref)/ancestor::device/@name"/>.
     <xsl:value-of select="fr:scada/fr:logicalDevice/fr:logicalNode/fr:datatype/id(@ref)/@name"/>

 </xsl:template>

</xsl:stylesheet>

但是id(@ref)接缝不起作用......

需要一些帮助我如何从XML文档中获得所需的输出

PLC1的MTU.t_1.speed,$ [MTU] .AGENT1.DEVICE1.ITEM1 ...

1 个答案:

答案 0 :(得分:0)

xslt中存在一些小问题。

首先要做xpath函数id(),你需要在你的xml文件(或dtd文件)中指定唯一的DOCTYPE声明。
表格xpath unique-id
元素节点可以具有唯一标识符(ID)。这是在DTD中声明为属性ID的属性的值。文档中没有两个元素可能具有相同的唯一ID。如果XML处理器将文档中的两个元素报告为具有相同的唯一ID(仅当文档无效时才可能),则必须将文档顺序中的第二个元素视为没有唯一ID。

类似的东西:

<!DOCTYPE HYDRO_P [
    <!ATTLIST item
       id     ID    #REQUIRED
    >
]>

尝试这个xpath:

<xsl:value-of select="id(fr:scada/fr:logicalDevice/fr:logicalNode/fr:datatype/@ref)/ancestor::fr:agent/@name"/> 

作为id函数和代理的参数的ref路径也属于manmspase“fr”。