mirror of
https://github.com/suk-ws/ph-Bookshelf.git
synced 2025-01-19 07:22:26 +08:00
更新为 version 2.0 配置文件格式,书籍目录添加 Separator 支持,解析器部分跟进更新
- 支持了新的 bookshelf 以及其中的 config/link/book 解析 - 支持了新的 page/chapter/separator 以及 root_book 的解析 - 暂不支持 book.xml 根配置的解析 - 添加了为 Separator 设置的 css 样式
This commit is contained in:
parent
7369ba23f3
commit
2fcdeafc72
@ -371,6 +371,15 @@ body {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#sidebar > .menu-container > .menu hr {
|
||||
width: calc(0.66 * calc(var(--sidebar-menu-container-padding-width) + 100%));
|
||||
margin: 0.55rem auto;
|
||||
transform: translate(calc(0px - var(--sidebar-menu-container-padding-width)/2), 0px);
|
||||
height: var(--sidebar-menu-list-seperator-width);
|
||||
border-radius: calc(var(--sidebar-menu-list-seperator-width) / 2);
|
||||
background: var(--color-menu-list-separator);
|
||||
}
|
||||
|
||||
#sidebar > .menu-container > .menu .menu-item {
|
||||
display: block;
|
||||
padding: 0.55rem 0;
|
||||
|
@ -1,46 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="https://book.sukazyo.cc/assets/xsd/book.xsd"
|
||||
xmlns="https://book.sukazyo.cc/assets/xsd/book.xsd"
|
||||
targetNamespace="https://book.sukazyo.cc"
|
||||
xmlns="https://book.sukazyo.cc"
|
||||
elementFormDefault="qualified"
|
||||
>
|
||||
|
||||
<xs:include schemaLocation="https://book.sukazyo.cc/assets/xsd/configuations.xsd" />
|
||||
|
||||
<xs:element name="Book" type="rootBook" />
|
||||
|
||||
<xs:complexType name="rootBook">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="bookChapter">
|
||||
<xs:attribute name="id" type="xs:string" use="required" />
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="bookChapter">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
|
||||
<xs:element name="Chapter">
|
||||
<xs:element name="Book">
|
||||
<xs:complexType>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="bookChapter">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
<xs:sequence>
|
||||
|
||||
<xs:element name="book_name" type="xs:string" />
|
||||
|
||||
<xs:element name="contents" type="bookContents" />
|
||||
|
||||
</xs:sequence>
|
||||
<xs:attribute name="version" type="xs:string" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="Page">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="id" type="xs:string" use="required" />
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attributeGroup ref="phb-config-level-page" />
|
||||
<xs:complexType name="bookContents">
|
||||
<xs:sequence>
|
||||
<xs:element name="Page" type="bookPage" />
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:group ref="bookContent" />
|
||||
<xs:element name="Separator" />
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:group name="bookContent">
|
||||
<xs:choice>
|
||||
|
||||
<xs:element name="Chapter" type="bookChapter" />
|
||||
|
||||
<xs:element name="Page" type="bookPage" />
|
||||
|
||||
</xs:choice>
|
||||
</xs:group>
|
||||
|
||||
<xs:complexType name="bookChapter">
|
||||
<xs:sequence>
|
||||
|
||||
<xs:element name="caption" type="xs:string" />
|
||||
|
||||
<xs:group ref="bookContent" maxOccurs="unbounded" />
|
||||
|
||||
</xs:sequence>
|
||||
<xs:attribute name="root" type="xs:string" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="bookPage">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="id" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="https://book.sukazyo.cc/assets/xsd/bookshelf.xsd"
|
||||
xmlns="https://book.sukazyo.cc/assets/xsd/bookshelf.xsd"
|
||||
targetNamespace="https://book.sukazyo.cc"
|
||||
xmlns="https://book.sukazyo.cc"
|
||||
elementFormDefault="qualified"
|
||||
>
|
||||
|
||||
@ -13,63 +13,77 @@
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
|
||||
<xs:element name="site_name" type="xs:string" />
|
||||
|
||||
<xs:element name="configurations" type="phb-config-level-site" />
|
||||
|
||||
<xs:element name="links" type="linkCollection" />
|
||||
|
||||
<xs:element name="books" type="bookCollection" />
|
||||
|
||||
<xs:element name="rootBook" type="rootBook" />
|
||||
|
||||
</xs:sequence>
|
||||
<xs:attribute name="siteName" type="xs:string" use="required" />
|
||||
<xs:element name="links">
|
||||
<xs:complexType>
|
||||
<xs:group ref="linkElement" maxOccurs="unbounded"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:complexType name="linkCollection">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:element name="books">
|
||||
<xs:complexType>
|
||||
<xs:group ref="bookElement" maxOccurs="unbounded" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="root_book" type="bookContents" />
|
||||
|
||||
</xs:sequence>
|
||||
<xs:attribute name="version" type="xs:string" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:group name="linkElement">
|
||||
<xs:choice>
|
||||
|
||||
<xs:element name="Link">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="href" type="xs:anyURI" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="Collection">
|
||||
<xs:complexType>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="linkCollection">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
<xs:sequence>
|
||||
<xs:element name="caption" type="xs:string" />
|
||||
<xs:group ref="linkElement" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:group>
|
||||
|
||||
<xs:complexType name="bookCollection">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:group name="bookElement">
|
||||
<xs:choice>
|
||||
|
||||
<xs:element name="Book">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="id" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="Collection">
|
||||
<xs:complexType>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="bookCollection">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
<xs:sequence>
|
||||
<xs:element name="caption" type="xs:string" />
|
||||
<xs:group ref="bookElement" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:group>
|
||||
|
||||
</xs:schema>
|
@ -1,30 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="https://book.sukazyo.cc/assets/xsd/configurations.xsd"
|
||||
xmlns="https://book.sukazyo.cc/assets/xsd/configurations.xsd"
|
||||
targetNamespace="https://book.sukazyo.cc"
|
||||
xmlns="https://book.sukazyo.cc"
|
||||
elementFormDefault="qualified"
|
||||
>
|
||||
|
||||
<xs:complexType name="phb-config-level-site">
|
||||
<xs:all minOccurs="0">
|
||||
<xs:element name="old.title.gen" type="xs:boolean" />
|
||||
<xs:element name="highlightjs" type="xs:boolean" />
|
||||
<xs:element name="highlightjs.languages" type="xs:string" />
|
||||
<xs:element name="highlightjs.theme" type="xs:string" />
|
||||
<xs:element name="codeblock.bg-color" type="xs:string" />
|
||||
<xs:element name="codeblock.fg-color" type="xs:string" />
|
||||
<xs:element name="codeblock.tab-size" type="xs:integer" />
|
||||
<xs:element name="regex.highlight" type="xs:boolean" />
|
||||
<xs:element name="listing.marker.rainbow" type="xs:boolean" />
|
||||
<xs:element name="title.permalink.flash" type="xs:boolean" />
|
||||
<xs:element name="web-title.rolling" type="xs:boolean" />
|
||||
<xs:element name="site.robots" type="xs:string" />
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" name="old.title.gen" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="highlightjs" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="highlightjs.languages" type="xs:string" />
|
||||
<xs:element minOccurs="0" name="highlightjs.theme" type="xs:string" />
|
||||
<xs:element minOccurs="0" name="codeblock.bg-color" type="xs:string" />
|
||||
<xs:element minOccurs="0" name="codeblock.fg-color" type="xs:string" />
|
||||
<xs:element minOccurs="0" name="codeblock.tab-size" type="xs:integer" />
|
||||
<xs:element minOccurs="0" name="regex.highlight" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="listing.marker.rainbow" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="title.permalink.flash" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="web-title.rolling" type="xs:boolean" />
|
||||
<xs:element minOccurs="0" name="site.robots" type="xs:string" />
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:attributeGroup name="phb-config-level-page">
|
||||
<xs:attribute name="old.title.gen" type="xs:boolean" />
|
||||
<xs:attribute name="old.title.gen" type="xs:boolean" />
|
||||
<xs:attribute name="highlightjs" type="xs:boolean" />
|
||||
<xs:attribute name="highlightjs.languages" type="xs:string" />
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
const APP_NAME = "ph-Bookshelf";
|
||||
|
||||
const VERSION = "0.4.0";
|
||||
const VERSION = "0.5.0-alpha1";
|
||||
const CHANNEL = "suk-ws";
|
||||
const BRANCH = "master";
|
||||
|
@ -20,26 +20,28 @@ class Book {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $xmlData
|
||||
* @param DOMNode $bookNode
|
||||
* @param BookCollection $parent
|
||||
* @return Book
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $xmlData, BookCollection $parent): Book {
|
||||
if ($xmlData->hasAttributes()) {
|
||||
$attrName = $xmlData->attributes->getNamedItem("name");
|
||||
$attrId = $xmlData->attributes->getNamedItem("id");
|
||||
if ($attrName == null)
|
||||
if ($attrId == null) throw new Exception("Book xml data missing attribute \"name\"");
|
||||
else throw new Exception("Book xml data with id \"$attrId->nodeValue\" missing attribute \"name\"");
|
||||
else $name = $attrName->nodeValue;
|
||||
if ($attrId == null) throw new Exception("Book xml data named \"$name\" missing attribute \"id\"");
|
||||
public static function parse (DOMNode $bookNode, BookCollection $parent): Book {
|
||||
if ($bookNode->hasAttributes()) {
|
||||
$attrId = $bookNode->attributes->getNamedItem("id");
|
||||
if ($attrId == null) throw new Exception("an Book xml data named missing attribute \"id\"");
|
||||
else $id = $attrId->nodeValue;
|
||||
} else
|
||||
throw new Exception("Book xml data missing attributes");
|
||||
if ($xmlData->hasChildNodes())
|
||||
throw new Exception("Book xml with id \"$id\" have some children which are not supported");
|
||||
return new Book($id, $name, $parent);
|
||||
$valueName = $bookNode->nodeValue;
|
||||
// if ($bookNode->hasChildNodes()) {
|
||||
// for ($child = $bookNode->firstChild; $child; $child = $child->nextSibling) {
|
||||
// $valueName .= match ($child->nodeName) {
|
||||
// "#text", "#cdata-section" => $child->nodeValue,
|
||||
// default => throw new Exception("Unsupported element type \"$child->nodeName\" in parsing configuration $bookNode->nodeName")
|
||||
// };
|
||||
// }
|
||||
// } // todo warn if no link name
|
||||
return new Book($id, $valueName, $parent);
|
||||
}
|
||||
|
||||
public function getId (): string {
|
||||
|
@ -23,23 +23,33 @@ class BookCollection {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $root
|
||||
* @param DOMNode $collectionNode
|
||||
* @param ?BookCollection $parent
|
||||
* @param bool $isRoot
|
||||
* @return BookCollection
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $root, ?BookCollection $parent, bool $isRoot = false): BookCollection {
|
||||
$name = BookCollection::ROOT;
|
||||
public static function parse (DOMNode $collectionNode, ?BookCollection $parent, bool $isRoot = false): BookCollection {
|
||||
$collectionName = LinkCollection::ROOT;
|
||||
$child = $collectionNode->firstChild;
|
||||
if ($child == null) throw new Exception("an BookCollection is NULL!");
|
||||
if (!$isRoot) {
|
||||
if ($root->hasAttributes()) {
|
||||
$attrName = $root->attributes->getNamedItem("name");
|
||||
if ($attrName == null) throw new Exception("BookCollection (not root) xml data missing attribute \"name\"");
|
||||
else $name = $attrName->nodeValue;
|
||||
} else throw new Exception("BookCollection (not root) xml data missing attributes");
|
||||
while ($child->nodeName != "caption") {
|
||||
switch ($child->nodeName) {
|
||||
case "#comment":
|
||||
break;
|
||||
case "#text":
|
||||
if (empty(trim($child->nodeValue))) break;
|
||||
default:
|
||||
throw new Exception("BookCollection need a \"caption\" as first child but \"$child->nodeName\" found");
|
||||
}
|
||||
$node = new BookCollection($name, $parent);
|
||||
for ($child = $root->firstChild; $child != null; $child = $child->nextSibling) {
|
||||
$child = $child->nextSibling;
|
||||
}
|
||||
$collectionName = $child->nodeValue;
|
||||
$child = $child->nextSibling;
|
||||
}
|
||||
$node = new BookCollection($collectionName, $parent);
|
||||
for (; $child != null; $child = $child->nextSibling) {
|
||||
switch ($child->nodeName) {
|
||||
case "Book":
|
||||
$node->array[] = Book::parse($child, $node);
|
||||
@ -51,9 +61,9 @@ class BookCollection {
|
||||
break;
|
||||
case "#text":
|
||||
if (empty(trim($child->nodeValue))) break;
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$name\"");
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$collectionName\"");
|
||||
default:
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$name\"");
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in BookCollection named \"$collectionName\"");
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
|
@ -44,6 +44,17 @@ class BookContented {
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $rootBookNode
|
||||
* @return BookContented
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parseRootBook (DOMNode $rootBookNode): BookContented {
|
||||
$return = new BookContented("%root", "");
|
||||
$return->childs = Chapter::parse($rootBookNode, null);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xmlContent
|
||||
* @return BookContented
|
||||
|
@ -28,12 +28,23 @@ class Chapter {
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $xmlData, ?Chapter $parent): Chapter {
|
||||
if ($xmlData->hasAttributes()) {
|
||||
$attrName = $xmlData->attributes->getNamedItem("name");
|
||||
if ($attrName == null) throw new Exception("Chapter xml data missing attribute \"name\"");
|
||||
else $node = new Chapter($xmlData->attributes->getNamedItem("name")->nodeValue, array(), $parent);
|
||||
} else throw new Exception("Chapter xml data missing attributes");
|
||||
for ($child = $xmlData->firstChild;$child != null ; $child = $child->nextSibling) {
|
||||
$child = $xmlData->firstChild;
|
||||
if ($parent != null) {
|
||||
while ($child->nodeName != "caption") {
|
||||
switch ($child->nodeName) {
|
||||
case "#comment":
|
||||
break;
|
||||
case "#text":
|
||||
if (empty(trim($child->nodeValue))) break;
|
||||
default:
|
||||
throw new Exception("Chapter need a \"caption\" as first child but \"$child->nodeName\" found");
|
||||
}
|
||||
$child = $child->nextSibling;
|
||||
}
|
||||
$node = new Chapter($child->nodeValue, array(), $parent);
|
||||
$child = $child->nextSibling;
|
||||
} else $node = new Chapter("", array(), $parent);
|
||||
for (;$child != null ; $child = $child->nextSibling) {
|
||||
switch ($child->nodeName) {
|
||||
case "Page":
|
||||
$node->children[] = Page::parse($child, $node);
|
||||
@ -41,6 +52,9 @@ class Chapter {
|
||||
case "Chapter":
|
||||
$node->children[] = self::parse($child, $node);
|
||||
break;
|
||||
case "Separator":
|
||||
$node->children[] = Separator::parse($child, $node);
|
||||
break;
|
||||
case "#comment":
|
||||
break;
|
||||
case "#text":
|
||||
|
@ -23,33 +23,19 @@ class Page {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $xmlData
|
||||
* @param DOMNode $pageNode
|
||||
* @param Chapter $parent
|
||||
* @return Page
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $xmlData, Chapter $parent): Page {
|
||||
if ($xmlData->hasAttributes()) {
|
||||
$attrName = $xmlData->attributes->getNamedItem("name");
|
||||
$attrId = $xmlData->attributes->getNamedItem("id");
|
||||
if ($attrName == null)
|
||||
if ($attrId == null) throw new Exception("Page xml data missing attribute \"name\"");
|
||||
else throw new Exception("Page xml data with id \"$attrId->nodeValue\" missing attribute \"name\"");
|
||||
else $name = $attrName->nodeValue;
|
||||
if ($attrId == null) throw new Exception("Page xml data named \"$name\" missing attribute \"id\"");
|
||||
public static function parse (DOMNode $pageNode, Chapter $parent): Page {
|
||||
if ($pageNode->hasAttributes()) {
|
||||
$attrId = $pageNode->attributes->getNamedItem("id");
|
||||
if ($attrId == null) throw new Exception("an Page xml data missing attribute \"id\"");
|
||||
else $id = $attrId->nodeValue;
|
||||
$node = new Page($id, $name, $parent);
|
||||
Bookshelf::parseConfigurationAttr($xmlData->attributes, $node->configurations, array("name", "id"));
|
||||
} else
|
||||
throw new Exception("Book xml data missing attributes");
|
||||
for ($child = $xmlData->firstChild; $child != null; $child = $child->nextSibling) {
|
||||
switch ($child->nodeName) {
|
||||
case "#text":
|
||||
default:
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in Page with id $id");
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
return new Page($id, $pageNode->nodeValue, $parent);
|
||||
}
|
||||
|
||||
public function getId (): string {
|
||||
|
38
src/Element/BookContent/Separator.php
Normal file
38
src/Element/BookContent/Separator.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace SukWs\Bookshelf\Element\BookContent;
|
||||
|
||||
use DOMNode;
|
||||
use Exception;
|
||||
|
||||
class Separator {
|
||||
|
||||
private Chapter $parent;
|
||||
|
||||
private function __construct (Chapter $parent) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $xmlData, ?Chapter $parent): Separator {
|
||||
if ($xmlData->hasAttributes() || $xmlData->hasChildNodes())
|
||||
throw new Exception("Separator need be clean with no any attr/children");
|
||||
if ($parent->getParent() != null)
|
||||
throw new Exception("Separator must in root contents path");
|
||||
return new Separator($parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Chapter
|
||||
*/
|
||||
public function getParent (): Chapter {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
public function getSummaryHtml (): string {
|
||||
return "<hr/>";
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,8 @@ use Exception;
|
||||
|
||||
class Bookshelf {
|
||||
|
||||
private string $configureVersion;
|
||||
|
||||
private string $siteName;
|
||||
|
||||
private LinkCollection $links;
|
||||
@ -32,9 +34,9 @@ class Bookshelf {
|
||||
if ($dom->hasAttributes() && $dom->hasChildNodes()) {
|
||||
|
||||
// Bookshelf 属性
|
||||
$attrSiteName = $dom->attributes->getNamedItem("siteName");
|
||||
if ($attrSiteName == null) throw new Exception("Bookshelf xml data missing attribute \"siteName\"");
|
||||
$return->siteName = $attrSiteName->nodeValue;
|
||||
$attrConfigVersion = $dom->attributes->getNamedItem("version");
|
||||
// todo no version warning
|
||||
$return->configureVersion = $attrConfigVersion->nodeValue;
|
||||
|
||||
// 对根节点的子节点进行遍历
|
||||
for ($rc = $dom->firstChild; $rc != null; $rc = $rc->nextSibling) {
|
||||
@ -45,12 +47,15 @@ class Bookshelf {
|
||||
case "books":
|
||||
$return->books = BookCollection::parse($rc, null, true);
|
||||
break;
|
||||
case "rootBook":
|
||||
$return->rootBook = BookContented::parse($rc);
|
||||
case "root_book":
|
||||
$return->rootBook = BookContented::parseRootBook($rc);
|
||||
break;
|
||||
case "configurations":
|
||||
self::parseConfiguration($rc, $return->configurations);
|
||||
break;
|
||||
case "site_name":
|
||||
$return->siteName = self::parseSiteName($rc);
|
||||
break;
|
||||
case "#comment":
|
||||
break;
|
||||
case "#text":
|
||||
@ -100,6 +105,19 @@ class Bookshelf {
|
||||
}
|
||||
}
|
||||
|
||||
private static function parseSiteName (DOMNode $siteNameNode): string {
|
||||
$siteNameValue = "";
|
||||
for ($child = $siteNameNode->firstChild; $child != null; $child = $child->nextSibling) {
|
||||
$siteNameValue .= match ($child->nodeName) {
|
||||
"#text", "#cdata-section" => $child->nodeValue,
|
||||
default => throw new Exception(
|
||||
"Unsupported element type \"$child->nodeName\" in parsing configuration $siteNameNode->nodeName"
|
||||
),
|
||||
};
|
||||
}
|
||||
return $siteNameValue;
|
||||
}
|
||||
|
||||
public function getSiteName (): string {
|
||||
return $this->siteName;
|
||||
}
|
||||
|
@ -18,26 +18,28 @@ class Link {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $xmlData
|
||||
* @param DOMNode $linkNode
|
||||
* @param LinkCollection $parent
|
||||
* @return Link
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $xmlData, LinkCollection $parent): Link {
|
||||
if ($xmlData->hasAttributes()) {
|
||||
$attrName = $xmlData->attributes->getNamedItem("name");
|
||||
$attrHref = $xmlData->attributes->getNamedItem("href");
|
||||
if ($attrName == null)
|
||||
if ($attrHref == null) throw new Exception("Link xml data missing attribute \"name\"");
|
||||
else throw new Exception("Link xml data which href is \"$attrHref->nodeValue\" missing attribute \"name\"");
|
||||
else $name = $attrName->nodeValue;
|
||||
if ($attrHref == null) throw new Exception("Link xml data named \"$name\" missing attribute \"href\"");
|
||||
public static function parse (DOMNode $linkNode, LinkCollection $parent): Link {
|
||||
if ($linkNode->hasAttributes()) {
|
||||
$attrHref = $linkNode->attributes->getNamedItem("href");
|
||||
if ($attrHref == null) throw new Exception("an Link data missing attribute \"href\"");
|
||||
else $href = $attrHref->nodeValue;
|
||||
} else
|
||||
throw new Exception("Link xml data missing attributes");
|
||||
if ($xmlData->hasChildNodes())
|
||||
throw new Exception("Link xml named \"$name\" have some children which are not supported");
|
||||
return new Link($name, $href, $parent);
|
||||
throw new Exception("an Link data missing attributes");
|
||||
$valueName = $linkNode->nodeValue;
|
||||
// if ($linkNode->hasChildNodes()) {
|
||||
// for ($child = $linkNode->firstChild; $child; $child = $child->nextSibling) {
|
||||
// $valueName .= match ($child->nodeName) {
|
||||
// "#text", "#cdata-section" => $child->nodeValue,
|
||||
// default => throw new Exception("Unsupported element type \"$child->nodeName\" in parsing configuration $linkNode->nodeName")
|
||||
// };
|
||||
// }
|
||||
// } // todo warn if no link name
|
||||
return new Link($valueName, $href, $parent);
|
||||
}
|
||||
|
||||
public function getName (): string {
|
||||
|
@ -22,23 +22,33 @@ class LinkCollection {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $root
|
||||
* @param DOMNode $collectionNode
|
||||
* @param ?LinkCollection $parent
|
||||
* @param bool $isRoot
|
||||
* @return LinkCollection
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parse (DOMNode $root, ?LinkCollection $parent, bool $isRoot = false): LinkCollection {
|
||||
$name = LinkCollection::ROOT;
|
||||
public static function parse (DOMNode $collectionNode, ?LinkCollection $parent, bool $isRoot = false): LinkCollection {
|
||||
$collectionName = LinkCollection::ROOT;
|
||||
$child = $collectionNode->firstChild;
|
||||
if ($child == null) throw new Exception("an LinkCollection is NULL!");
|
||||
if (!$isRoot) {
|
||||
if ($root->hasAttributes()) {
|
||||
$attrName = $root->attributes->getNamedItem("name");
|
||||
if ($attrName == null) throw new Exception("LinkCollection (not root) xml data missing attribute \"name\"");
|
||||
else $name = $attrName->nodeValue;
|
||||
} else throw new Exception("LinkCollection (not root) xml data missing attributes");
|
||||
while ($child->nodeName != "caption") {
|
||||
switch ($child->nodeName) {
|
||||
case "#comment":
|
||||
break;
|
||||
case "#text":
|
||||
if (empty(trim($child->nodeValue))) break;
|
||||
default:
|
||||
throw new Exception("LinkCollection need a \"caption\" as first child but \"$child->nodeName\" found");
|
||||
}
|
||||
$node = new LinkCollection($name, $parent);
|
||||
for ($child = $root->firstChild; $child != null; $child = $child->nextSibling) {
|
||||
$child = $child->nextSibling;
|
||||
}
|
||||
$collectionName = $child->nodeValue;
|
||||
$child = $child->nextSibling;
|
||||
}
|
||||
$node = new LinkCollection($collectionName, $parent);
|
||||
for (; $child != null; $child = $child->nextSibling) {
|
||||
switch ($child->nodeName) {
|
||||
case "Link":
|
||||
$node->array[] = Link::parse($child, $node);
|
||||
@ -50,9 +60,9 @@ class LinkCollection {
|
||||
break;
|
||||
case "#text":
|
||||
if (empty(trim($child->nodeValue))) break;
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$name\"");
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$collectionName\"");
|
||||
default:
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$name\"");
|
||||
throw new Exception("Unsupported element type \"$child->nodeName\" in LinkCollection named \"$collectionName\"");
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
|
Loading…
Reference in New Issue
Block a user