1

我正在学习 XPath,在练习使用我在网上找到的示例 xml 文件时,在将 XSL 文件实施到项目中后,应用程序无法呈现任何值。非常感谢任何关于我遗漏或做错的建议。

XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <Customers>
        <Customer>
            <Id>1</Id>
            <FirstName>Joe</FirstName>
            <Surname>Doe</Surname>
        </Customer>
   </Customers>
    <Customers>
          <Customer>
            <Id>2</Id>
            <FirstName>Mary</FirstName>
            <Surname>Brown</Surname>
        </Customer>
    </Customers>
    <Customers>
        <Customer>
            <Id>3</Id>
            <FirstName>Paul</FirstName>
            <Surname>Smith</Surname>
        </Customer>
    </Customers>
    </root>

XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:template match ="/">
        <root>
            <xsl:apply-templates select ="//Customers"/>
        </root>
    </xsl:template>
    <xsl:template match ="//Customer">
        <Customer>
            <xsl:attribute name="Id">
                <xsl:value-of select="Id"/>
            </xsl:attribute>
            <xsl:attribute name="FirstName">
                <xsl:value-of select="FirstName"/>
            </xsl:attribute>
            <xsl:attribute name="Surname">
                <xsl:value-of select="Surname"/>
            </xsl:attribute>
        </Customer>
    </xsl:template>
</xsl:stylesheet>

ASPX:

<asp:XmlDataSource ID="XmlDataSource1" runat="server" 
            DataFile="~/xml/Sample-no-attributes.xml" 
            TransformFile="~/xml/Sample-no-attributes.xsl"
            XPath="/root/Customers">
      </asp:XmlDataSource>

        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            DataSourceID="XmlDataSource1">
            <Columns>
                 <asp:TemplateField HeaderText="CustomerID">
            <ItemTemplate>
                <%# XPath("Customer/Id")%>
             </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="First Name">
            <ItemTemplate>
                <%# XPath("Customer/FirstName")%>
             </ItemTemplate>
            </asp:TemplateField>

             <asp:TemplateField HeaderText="Surname">
            <ItemTemplate>
                <%# XPath("Customer/Surname")%>
             </ItemTemplate>
            </asp:TemplateField>
            </Columns>
        </asp:GridView>

请就我在这里做错的事情提供一些帮助。

4

1 回答 1

1

测试您的 XSLT 显示输出 XML 如下:

<root>
    <Customer Id="1" FirstName="Joe" Surname="Doe"/>
    <Customer Id="2" FirstName="Mary" Surname="Brown"/>
    <Customer Id="3" FirstName="Paul" Surname="Smith"/>
</root>

如果您注意到,这里没有出现客户元素,但是您的 asp:XmlDataSource 中的 XPath 表达式是“/root/Customers”。

假设您确实想删除Customers元素,您首先需要相应地更改 Xpath 表达式

XPath="/root/Customer"

但是您的项目模板中的 XPath 表达式也有问题

    <ItemTemplate>
        <%# XPath("Customer/Id")%>
    </ItemTemplate>

使用当前修复,您需要从表达式中删除Customer,因为您现在将定位在Customer元素上。而且,在您的输出 XML 中,Id现在是一个属性,而不是子元素。这意味着您的 Xpath 必须是这样的(注意用于属性的 @ 符号)

    <ItemTemplate>
        <%# XPath("@Id")%>
    </ItemTemplate>

试试这个 ASPX

 <asp:XmlDataSource ID="XmlDataSource1" runat="server" 
        DataFile="~/Sample-no-attributes.xml" 
        TransformFile="~/Sample-no-attributes.xsl"
        XPath="/root/Customer">
  </asp:XmlDataSource>

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        DataSourceID="XmlDataSource1">
        <Columns>
             <asp:TemplateField HeaderText="CustomerID">
        <ItemTemplate>
            <%# XPath("@Id")%>
         </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="First Name">
        <ItemTemplate>
            <%# XPath("@FirstName")%>
         </ItemTemplate>
        </asp:TemplateField>

         <asp:TemplateField HeaderText="Surname">
        <ItemTemplate>
            <%# XPath("@Surname")%>
         </ItemTemplate>
        </asp:TemplateField>
        </Columns>
    </asp:GridView>

请注意,如果您确实想在您的 XSLT 中保留客户,那么可能值得了解他们为什么会丢失。在您的第一个模板中,您执行此操作

<xsl:apply-templates select ="//Customers"/>

但是您的 XSLT 中没有匹配客户的模板。发生这种情况时,将应用 XSLT 的内置模板。这些输出元素内的任何文本节点,然后查找与其子元素匹配的模板。但它不会输出元素本身。因此,您失去了客户元素。

要保留它,您可以添加以下模板

 <xsl:template match ="Customers">
    <Customers>
      <xsl:apply-templates select ="Customer"/>
    </Customers>
 </xsl:template>

但是,最好在此处使用XSLT 身份转换来复制现有元素。

试试这个 XLST,它保留了Customers元素。请注意您不需要显式模板来匹配RootCustomers。还要注意使用属性值模板来输出每个客户元素的属性,从而使代码不那么冗长。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

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

  <xsl:template match ="//Customer">
    <Customer Id="{Id}" FirstName="{FirstName}" Surname="{Surname}" />
  </xsl:template>
</xsl:stylesheet>

如果您确实使用了此 XSLT,则 asp:XmlDataSource 的 XPath 将保持为“/root/Customers”,但 ItemTemplates 的 XPath 将是<%# XPath("Customer/@Id")%>

于 2013-08-04T08:41:16.467 回答