2

XMLは初めてです。アイテムの詳細を含むテーブルと、選択リストの各注文の顧客の詳細を含む別のテーブルを作成しようとしています。簡単そうに見えますが、注文数だけ繰り返されたすべての注文のすべてのアイテムのリストを取得します。私は何が間違っているのですか?(以下のXSLコード...)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" doctype-system="about:legacy-compat"/>
<xsl:template match="/">

<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" type="css/text" href="style.css"/>
<title>Orders</title>
</head>

<body>
<xsl:for-each select="//order">
<table>
<caption><h3>Order Information</h3></caption>
<thead>
<th align="left">Item Id</th>
<th align="left">Item Description</th>
<th align="left">Quantity</th>
<th align="left">Price</th>
</thead>
<xsl:for-each select="//item">
<tr>
<td align="left"><xsl:value-of select="itemId"/></td>
<td align="left"><xsl:value-of select="itemName"/></td>
<td align="left"><xsl:value-of select="quantity"/></td>
<td align="left"><xsl:value-of select="price"/></td>
</tr>
</xsl:for-each>
</table>
<table>
<caption><h3>Customer Information</h3></caption>
<thead>
<th align="left">Customer Name</th>
<th align="left">Street</th>
<th align="left">City</th>
</thead>
<xsl:for-each select="//item">
<tr>
<td align="left"><xsl:value-of select="customerName"/></td>
<td align="left"><xsl:value-of select="street"/></td>
<td align="left"><xsl:value-of select="city"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</body>
</html>

</xsl:template>
</xsl:stylesheet>

これはXMLです:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="Orders.xsl"?>

<orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Orders.xsd">
<order>
<orderId>123</orderId>
<items>
<item>
<itemId>001</itemId>
<itemName>Nylon Rope</itemName>
<quantity>1</quantity>
<price>3.50</price>
</item>
<item>
<itemId>002</itemId>
<itemName>Shovel</itemName>
<quantity>1</quantity>
<price>24.95</price>
</item>
</items>
<customerAddress>
<customerName>Larry Murphy</customerName>
<street>Shallowgrave Lane</street>
<city>Ballymore Eustace, Co. Kildare</city>
</customerAddress>
</order>
<order>
<orderId>124</orderId>
<items>
<item>
<itemId>001</itemId>
<itemName>Whiskey</itemName>
<quantity>1</quantity>
<price>18.50</price>
</item>
<item>
<itemId>002</itemId>
<itemName>Shotgun</itemName>
<quantity>1</quantity>
<price>225</price>
</item>
<item>
<itemId>003</itemId>
<itemName>Cartridge</itemName>
<quantity>1</quantity>
<price>1.85</price>
</item>
</items>
<customerAddress>
<customerName>Enda Kenny</customerName>
<street>A Avenue</street>
<city>Castlebar, Co. Mayo</city>
</customerAddress>
</order>
</orders>

関連するXSD:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="orders">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="order"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="order">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="items"/>
<xsd:element maxOccurs="1" minOccurs="1" ref="customerAddress"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="items">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="item"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="item">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="itemId"/>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="itemName"/>
<xsd:element maxOccurs="unbounded" minOccurs="1" ref="quantity"/>
<xsd:element maxoccurs="unbounded" minOccurs="1" ref="price"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="customerAddress">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" ref="customerName"/>
<xsd:element maxOccurs="1" minOccurs="1" ref="street"/>
<xsd:element maxOccurs="1" minOccurs="1" ref="city"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="itemId" type="xsd:string"/>
<xsd:element name="itemName" type="xsd:string"/>
<xsd:element name="quantity" type="xsd:int"/>
<xsd:element name="price" type="xsd:double"/>
<xsd:element name="customerName" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>

</xsd:schema>
4

3 に答える 3

3
<xsl:for-each select="//order">

ドキュメント内のすべての<order>タグを選択します。

<xsl:for-each select="//item">

同様<item>に、ドキュメント内のすべてのタグを選択します。これが、表示される結果が得られる理由です。

必要なのは

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

説明は、//それ自体が単にdescendant-or-selfルート要素を意味するということです。.//一方、現在の要素(この場合は<order>要素)の子孫または自己を意味するため、アイテムは正しくグループ化されます。

これについては、ここで詳しく読むことができます(実際に読む必要があります)。軸とコンテキストノードを理解することは、XSLT / XPathがどのように機能するかを理解するために重要であり、多くの苦痛を軽減します。

于 2012-10-15T22:58:40.920 に答える
1

//を使用しないでください-この方法では、コンテキストノードに関連する要素ではなく、常にxmlドキュメントからすべての要素を選択します。

于 2012-10-15T22:58:18.453 に答える
0

次のようなものを試してください(テストされていません。2つの内部ループをtemplate / apply-templatesに置き換えることもできます)。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" doctype-system="about:legacy-compat" />
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta charset="utf-8" />
                <link rel="stylesheet" type="css/text" href="style.css" />
                <title>Orders</title>
            </head>

            <body>
                <xsl:apply-templates select="//order" />
            </body>
        </html>
    </xsl:template>
    <xsl:template match="//order">
        <table>
            <caption>
                <h3>Order Information</h3>
            </caption>
            <thead>
                <th align="left">Item Id</th>
                <th align="left">Item Description</th>
                <th align="left">Quantity</th>
                <th align="left">Price</th>
            </thead>
            <xsl:for-each select="//item">
                <tr>
                    <td align="left">
                        <xsl:value-of select="itemId" />
                    </td>
                    <td align="left">
                        <xsl:value-of select="itemName" />
                    </td>
                    <td align="left">
                        <xsl:value-of select="quantity" />
                    </td>
                    <td align="left">
                        <xsl:value-of select="price" />
                    </td>
                </tr>
            </xsl:for-each>
        </table>
        <table>
            <caption>
                <h3>Customer Information</h3>
            </caption>
            <thead>
                <th align="left">Customer Name</th>
                <th align="left">Street</th>
                <th align="left">City</th>
            </thead>
            <xsl:for-each select="//item">
                <tr>
                    <td align="left">
                        <xsl:value-of select="customerName" />
                    </td>
                    <td align="left">
                        <xsl:value-of select="street" />
                    </td>
                    <td align="left">
                        <xsl:value-of select="city" />
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

私は通常、再利用性のためにテンプレートを使用します。

<xsl:template match="Menu">
<xsl:template match="MenuItem">

そして、私がそれらを必要とするところならどこでも:

<xsl:apply-templates select="/MenuRoot/Menu" />
<xsl:apply-templates select="/MenuRoot/MenuItem" />

あなたの場合match="/order/item"、そしてmatch="/order/customer/item"(構造の単なる推測)を使用することができ、より具体的にするようにしてください。

于 2012-10-15T23:02:57.367 に答える