一个 XML 文件本质上由两部分组成:
- <posts> - 包含里面的帖子
- <users> - 里面包含有关用户的信息
xml 示例:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>
<blog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org blog.xsd">
<posts>
<post>
<topic>Human Resource Machine</topic>
<keyword>C#</keyword>
<keyword>Game</keyword>
<keyword>HRM</keyword>
<date>2020-12-03</date>
<message>Пишу тут клон игры Human Resource Machine для лабы по шарпу)))</message>
<file src="images/hrm.gif" name="hrm"/>
<comment user="1">
<date>2020-12-03</date>
<message>А на чем пишешь-то?</message>
<comment user="0">
<date>2020-12-03</date>
<message>На винформах)))</message>
<comment user="1">
<date>2020-12-03</date>
<message>Ты псих...</message>
<comment user="0">
<date>2020-12-03</date>
<message>Я знаю...</message>
</comment>
</comment>
</comment>
</comment>
</post>
</posts>
<users>
<user id="0" admin="true">
<name>A.L.E.X.</name>
<phone>+380990315102</phone>
<mail>akrutko472@gmail.com</mail>
</user>
<user id="1" admin="false">
<name>XXX</name>
<phone>+88005553535</phone>
<mail>xxx@gmail.com</mail>
</user>
</users>
</blog>
通过 xsd 获得更多详细信息:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:simpleType name="nameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"></xs:minLength>
<xs:maxLength value="25"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name = "phoneType">
<xs:restriction base="xs:string">
<xs:pattern value="^\+? ?\d([ -]?\d){9,14}$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name = "mailType">
<xs:restriction base="xs:string">
<xs:pattern value="^\w[\.\w]*@[\w]+\.[A-Za-z]+$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="messageType">
<xs:restriction base="xs:string">
<xs:maxLength value="1000"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="fileType">
<xs:attribute name="src" type="xs:anyURI" use="required"/>
<xs:attribute name="name" type="nameType" use="optional" />
</xs:complexType>
<xs:complexType name="postType">
<xs:sequence>
<xs:element name="topic" type="nameType"></xs:element>
<xs:element name="keyword" type="nameType" minOccurs="0" maxOccurs="unbounded"></xs:element>
<xs:element name="date" type="xs:date"></xs:element>
<xs:element name="message" type="messageType"></xs:element>
<xs:element name="file" type="fileType" minOccurs="0" maxOccurs="10"></xs:element>
<xs:element name="comment" type="commentType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="commentType">
<xs:sequence>
<xs:element name="date" type="xs:date"></xs:element>
<xs:element name="message" type="messageType"></xs:element>
<xs:element name="file" type="fileType" minOccurs="0" maxOccurs="3"></xs:element>
<xs:element name="comment" type="commentType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
<xs:attribute name="user" type="xs:nonNegativeInteger" use="required"/>
</xs:complexType>
<xs:complexType name="userType">
<xs:sequence>
<xs:element name="name" type="nameType"/>
<xs:element name="phone" type="phoneType"/>
<xs:element name="mail" type="mailType"/>
</xs:sequence>
<xs:attribute name="id" type="xs:nonNegativeInteger" use="required"/>
<xs:attribute name="admin" type="xs:boolean" default="false"/>
</xs:complexType>
<xs:complexType name="postsType">
<xs:sequence>
<xs:element name = "post" type="postType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name ="usersType">
<xs:sequence>
<xs:element name = "user" type="userType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="blogType">
<xs:sequence>
<xs:element name="posts" type="postsType"></xs:element>
<xs:element name="users" type="usersType"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name ="blog" type="blogType"></xs:element>
</xs:schema>
在 XSLT 中,我想直接在评论中呈现用户的昵称。而此时,困难就来了(这一行在特定的<comment>范围内被调用):
<xsl:value-of select="/blog/users/user[@id = '{@user}']/name"/>
理论上,一切都是正确的,但最终什么也没有发生。在这种情况下,特殊情况起作用,例如:
<xsl:value-of select="/blog/users/user[@id = '1']/name"/>
我还在关卡上渲染了一些东西:
<p class="/blog/users/user[@id = '{@user}']/name"/>
在呈现的页面中,<p> 类实际上是正确的,即 XPath 本身是正确编写的,但由于某种原因,XSLT 不希望在 <xsl:value-of> 内正确处理路径。唯一的建议是为此还有另一个 xsl - 我什至不怀疑存在的指令。您也可能需要为此使用变量,我尝试了很多 - 最后什么也没发生。还是问题的本质是别的?
最被截断的 xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--Рекурсивно вызываемый шаблон комментария-->
<xsl:template name="comment">
<div class="comment">
<p class="author">
<xsl:value-of select="/blog/users/user[@id = '1']/name"/> <!--Конкретный пользователь - работает-->
<p class="/blog/users/user[@id = '{@user}']/name"/> <!--XPath как класс <p> - значение корректно-->
<xsl:value-of select="/blog/users/user[@id = '{@user}']/name"/> <!--Уже не работает...-->
</p>
<p><xsl:value-of select="message"/></p>
<div class="info"><xsl:value-of select="date"/></div>
<xsl:if test="comment">
<hr/>
<details>
<summary>Ответы</summary>
<xsl:for-each select="comment">
<xsl:call-template name="comment"/>
</xsl:for-each>
</details>
</xsl:if>
</div>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<meta charset = "UTF-8"/>
<title>Блог</title>
<link rel = "stylesheet" href = "styles/main.css"/>
<script src="scripts/main.js" defer="true"></script>
</head>
<body>
<xsl:for-each select="blog/posts/post">
<div class="post">
<div class="topic"><xsl:value-of select="topic"/></div>
<div class = "keywords">
<xsl:for-each select="keyword">
<span><xsl:value-of select="."/></span>
</xsl:for-each>
</div>
<p><xsl:value-of select="message"/></p>
<div class="info"><xsl:value-of select="date"/></div>
<xsl:if test="comment">
<hr/>
<details>
<summary>Комментарии</summary>
<xsl:for-each select="comment">
<xsl:call-template name="comment"/>
</xsl:for-each>
</details>
</xsl:if>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
预期结果:
这是一个不提供后端的实验室作业,因此不使用 xslt 处理器。换句话说,xslt 处理器内置在浏览器中。
事实证明一切都更加平庸和简单:
正确的答案总是最无聊的……
这是一个正确的假设。只需要一个设置。这是优于简单变量的首选方法。
请参阅下面的操作方法。
XSLT