Skip to content

Commit 4bda0be

Browse files
committed
feat: ✨ 添加快捷函数
1 parent 5a08a0e commit 4bda0be

File tree

5 files changed

+165
-125
lines changed

5 files changed

+165
-125
lines changed

dist/xpath-selector.lib.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10602,14 +10602,28 @@ ${d2}`);
1060210602
}
1060310603
return returnTypeMap[returnType];
1060410604
}
10605-
function xpathSelector2(options) {
10606-
return fontoxpath.evaluateXPath(
10607-
options.expression,
10608-
options.node || document,
10609-
null,
10610-
null,
10611-
returnTypeTransition(options.returnType)
10612-
);
10605+
function createXPathSelector() {
10606+
function xpathSelector2(options) {
10607+
return fontoxpath.evaluateXPath(
10608+
options.expression,
10609+
options.node || document,
10610+
null,
10611+
null,
10612+
returnTypeTransition(options.returnType)
10613+
);
10614+
}
10615+
xpathSelector2.selectString = (expression, node) => xpathSelector2({ expression, node, returnType: "string" });
10616+
xpathSelector2.selectStrings = (expression, node) => xpathSelector2({ expression, node, returnType: "strings" });
10617+
xpathSelector2.selectNumber = (expression, node) => xpathSelector2({ expression, node, returnType: "number" });
10618+
xpathSelector2.selectNumbers = (expression, node) => xpathSelector2({ expression, node, returnType: "numbers" });
10619+
xpathSelector2.selectBoolean = (expression, node) => xpathSelector2({ expression, node, returnType: "boolean" });
10620+
xpathSelector2.selectNodes = (expression, node) => xpathSelector2({ expression, node, returnType: "nodes" });
10621+
xpathSelector2.selectFirstNode = (expression, node) => xpathSelector2({ expression, node, returnType: "first-node" });
10622+
xpathSelector2.selectMap = (expression, node) => xpathSelector2({ expression, node, returnType: "map" });
10623+
xpathSelector2.selectArray = (expression, node) => xpathSelector2({ expression, node, returnType: "array" });
10624+
xpathSelector2.selectAllResults = (expression, node) => xpathSelector2({ expression, node, returnType: "all-results" });
10625+
return xpathSelector2;
1061310626
}
10614-
return xpathSelector2;
10627+
const index = createXPathSelector();
10628+
return index;
1061510629
}();

libs/xpath-selector/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @xiaohuohumax/xpath-selector
22

3+
## 1.1.0
4+
5+
### Minor Changes
6+
7+
- 添加快捷函数
8+
39
## 1.0.6
410

511
### Patch Changes

libs/xpath-selector/README.md

Lines changed: 96 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
## 📥 参数说明
1919

20+
### 通用函数 xpathSelector(options: Options)
21+
2022
**Options 参数说明:**
2123

2224
| 参数名 | 类型 | 是否必填 | 默认值 | 说明 |
@@ -25,28 +27,6 @@
2527
| `returnType` | string || | 获取结果的类型,可选值:`string``strings``number``numbers``boolean``nodes``first-node``map``array``all-results` |
2628
| `node` | Node || `document` | 要搜索的节点 |
2729

28-
## 📦 使用示例
29-
30-
```html
31-
<!DOCTYPE html>
32-
<html lang="en" charset="UTF-8">
33-
<head>
34-
<title>hello world</title>
35-
</head>
36-
<body>
37-
<p>hello</p>
38-
<p>world</p>
39-
<a href="#">hello</a>
40-
<a href="#">world</a>
41-
<section>
42-
<!-- section内容 -->
43-
</section>
44-
</body>
45-
</html>
46-
```
47-
48-
**获取 title 节点的文本内容**
49-
5030
```typescript
5131
const title = xpathSelector({
5232
expression: '//title/text()',
@@ -55,78 +35,19 @@ const title = xpathSelector({
5535
console.log(title) // hello world
5636
```
5737

58-
**获取所有 p 节点的文本内容**
59-
60-
```typescript
61-
const pList = xpathSelector({
62-
expression: '//p/text()',
63-
returnType: 'strings'
64-
})
65-
console.log(pList) // ['hello', 'world']
66-
```
67-
68-
**统计所有 a 节点的个数**
38+
### 快捷函数 xpathSelector.select[returnType](expression: string, node?: Node)
6939

70-
```typescript
71-
const aCount = xpathSelector({
72-
expression: 'count(//a)',
73-
returnType: 'number'
74-
})
75-
console.log(aCount) // 2
76-
```
77-
78-
**判断是否存在 section 节点**
79-
80-
```typescript
81-
const hasSection = xpathSelector({
82-
expression: 'boolean(//section)',
83-
returnType: 'boolean'
84-
})
85-
console.log(hasSection) // true
86-
```
87-
88-
**获取全部的 a 节点**
89-
90-
```typescript
91-
const aList = xpathSelector({
92-
expression: '//a',
93-
returnType: 'nodes'
94-
})
95-
console.log(aList) // [<a>hello</a>, <a>world</a>]
96-
```
97-
98-
**获取第一个 a 节点**
99-
100-
```typescript
101-
const firstA = xpathSelector({
102-
expression: '//a',
103-
returnType: 'first-node'
104-
})
105-
console.log(firstA) // <a>hello</a>
106-
```
107-
108-
**获取 html 节点的全部属性**
109-
110-
```typescript
111-
const htmlAttributes = xpathSelector({
112-
expression: `map:merge(
113-
for $attr in //html/@*
114-
return map:entry(local-name($attr), string($attr))
115-
)`,
116-
returnType: 'map'
117-
})
118-
console.log(htmlAttributes) // {lang: "en", charset: "UTF-8"}
119-
```
40+
**Options 参数说明:**
12041

121-
**获取自定义 html 节点的 title 节点的文本内容**
42+
| 参数名 | 类型 | 是否必填 | 默认值 | 说明 |
43+
| ------------ | ------ | -------- | ---------- | ------------------------------------------------ |
44+
| `returnType` | string || | 函数名,可选值见上方 Options.returnType 参数说明 |
45+
| `expression` | string || | 要获取的节点的 XPath 表达式 |
46+
| `node` | Node || `document` | 要搜索的节点 |
12247

12348
```typescript
124-
const customHtmlTitle = xpathSelector({
125-
expression: '//title/text()',
126-
node: new DOMParser().parseFromString('<html><title>Hello</title></html>', 'text/html'),
127-
returnType: 'string',
128-
})
129-
console.log(customHtmlTitle) // Hello
49+
const title = xpathSelector.selectString('//title/text()')
50+
console.log(title) // hello world
13051
```
13152

13253
## 📖 使用方式
@@ -140,10 +61,7 @@ console.log(customHtmlTitle) // Hello
14061

14162
(function () {
14263
'use strict'
143-
const title = xpathSelector({
144-
expression: '//title/text()',
145-
returnType: 'string'
146-
})
64+
const title = xpathSelector.selectString('//title/text()')
14765
console.log(title) // hello world
14866
})()
14967
```
@@ -167,19 +85,8 @@ npm i @xiaohuohumax/xpath-selector
16785
```typescript
16886
import xpathSelector from '@xiaohuohumax/xpath-selector'
16987

170-
const title = xpathSelector({
171-
expression: '//title/text()',
172-
returnType: 'string'
173-
})
174-
175-
console.log(title) // Output: "Test Page"
176-
177-
const links = xpathSelector<HTMLAnchorElement, 'nodes'>({
178-
expression: '//a',
179-
returnType: 'nodes',
180-
})
181-
182-
console.log(links) // Output: [<a href="#">Hello</a>, <a href="#">World</a>]
88+
const button = xpathSelector.selectFirstNode<HTMLButtonElement>('//button')
89+
console.log(button) // Output: <button>Click Me</button>
18390
```
18491

18592
4. 修改 vite.config.ts 排除 xpath-selector 依赖
@@ -202,6 +109,88 @@ export default defineConfig({
202109
})
203110
```
204111

112+
## 📦 使用示例
113+
114+
```html
115+
<!DOCTYPE html>
116+
<html lang="en" charset="UTF-8">
117+
<head>
118+
<title>hello world</title>
119+
</head>
120+
<body>
121+
<p>hello</p>
122+
<p>world</p>
123+
<a href="#">hello</a>
124+
<a href="#">world</a>
125+
<section>
126+
<!-- section内容 -->
127+
</section>
128+
</body>
129+
</html>
130+
```
131+
132+
**获取 title 节点的文本内容**
133+
134+
```typescript
135+
const title = xpathSelector.selectString('//title/text()')
136+
console.log(title) // hello world
137+
```
138+
139+
**获取所有 p 节点的文本内容**
140+
141+
```typescript
142+
const pList = xpathSelector.selectStrings('//p/text()')
143+
console.log(pList) // ['hello', 'world']
144+
```
145+
146+
**统计所有 a 节点的个数**
147+
148+
```typescript
149+
const aCount = xpathSelector.selectNumber('count(//a)')
150+
console.log(aCount) // 2
151+
```
152+
153+
**判断是否存在 section 节点**
154+
155+
```typescript
156+
const hasSection = xpathSelector.selectBoolean('boolean(//section)')
157+
console.log(hasSection) // true
158+
```
159+
160+
**获取全部的 a 节点**
161+
162+
```typescript
163+
const aList = xpathSelector.selectNodes('//a')
164+
console.log(aList) // [<a>hello</a>, <a>world</a>]
165+
```
166+
167+
**获取第一个 a 节点**
168+
169+
```typescript
170+
const firstA = xpathSelector.selectFirstNode('//a')
171+
console.log(firstA) // <a>hello</a>
172+
```
173+
174+
**获取 html 节点的全部属性**
175+
176+
```typescript
177+
const htmlAttributes = xpathSelector.selectMap(`map:merge(
178+
for $attr in //html/@*
179+
return map:entry(local-name($attr), string($attr))
180+
)`)
181+
console.log(htmlAttributes) // {lang: "en", charset: "UTF-8"}
182+
```
183+
184+
**获取自定义 html 节点的 title 节点的文本内容**
185+
186+
```typescript
187+
const customHtmlTitle = xpathSelector.selectString(
188+
'//title/text()',
189+
new DOMParser().parseFromString('<html><title>Hello</title></html>', 'text/html'),
190+
)
191+
console.log(customHtmlTitle) // Hello
192+
```
193+
205194
## 🧩 依赖项目
206195

207196
- [fontoxpath](https://github.com/FontoXML/fontoxpath) XPath 引擎

libs/xpath-selector/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@xiaohuohumax/xpath-selector",
33
"type": "module",
4-
"version": "1.0.6",
4+
"version": "1.1.0",
55
"description": "XPath Selector -- 一个 XPath 选择器库,快速获取节点数据",
66
"author": {
77
"name": "xiaohuohumax",

libs/xpath-selector/src/index.ts

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,43 @@ function returnTypeTransition<T extends ReturnType>(returnType: T): ReturnTypeTr
5252
return returnTypeMap[returnType]
5353
}
5454

55-
export default function xpathSelector<N extends fontoxpath.Node, T extends ReturnType>(options: Options<T>) {
56-
return fontoxpath.evaluateXPath<N, ReturnTypeTransition<T>>(
57-
options.expression,
58-
options.node || document,
59-
null,
60-
null,
61-
returnTypeTransition(options.returnType),
62-
)
55+
export interface XPathSelector {
56+
<N extends fontoxpath.Node, T extends ReturnType>(options: Options<T>): fontoxpath.IReturnTypes<N>[ReturnTypeTransition<T>]
57+
selectString: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'string'>]
58+
selectStrings: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'strings'>]
59+
selectNumber: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'number'>]
60+
selectNumbers: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'numbers'>]
61+
selectBoolean: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'boolean'>]
62+
selectNodes: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'nodes'>]
63+
selectFirstNode: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'first-node'>]
64+
selectMap: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'map'>]
65+
selectArray: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'array'>]
66+
selectAllResults: <N extends fontoxpath.Node>(expression: string, node?: Node) => fontoxpath.IReturnTypes<N>[ReturnTypeTransition<'all-results'>]
6367
}
68+
69+
function createXPathSelector(): XPathSelector {
70+
function xpathSelector<N extends fontoxpath.Node, T extends ReturnType>(options: Options<T>) {
71+
return fontoxpath.evaluateXPath<N, ReturnTypeTransition<T>>(
72+
options.expression,
73+
options.node || document,
74+
null,
75+
null,
76+
returnTypeTransition(options.returnType),
77+
)
78+
}
79+
80+
xpathSelector.selectString = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'string'>({ expression, node, returnType: 'string' })
81+
xpathSelector.selectStrings = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'strings'>({ expression, node, returnType: 'strings' })
82+
xpathSelector.selectNumber = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'number'>({ expression, node, returnType: 'number' })
83+
xpathSelector.selectNumbers = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'numbers'>({ expression, node, returnType: 'numbers' })
84+
xpathSelector.selectBoolean = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'boolean'>({ expression, node, returnType: 'boolean' })
85+
xpathSelector.selectNodes = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'nodes'>({ expression, node, returnType: 'nodes' })
86+
xpathSelector.selectFirstNode = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'first-node'>({ expression, node, returnType: 'first-node' })
87+
xpathSelector.selectMap = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'map'>({ expression, node, returnType: 'map' })
88+
xpathSelector.selectArray = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'array'>({ expression, node, returnType: 'array' })
89+
xpathSelector.selectAllResults = <N extends fontoxpath.Node>(expression: string, node?: Node) => xpathSelector<N, 'all-results'>({ expression, node, returnType: 'all-results' })
90+
91+
return xpathSelector
92+
}
93+
94+
export default createXPathSelector()

0 commit comments

Comments
 (0)