-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
문제현상
#576 의 구현내용에 따르면, page.xhtml 파일의 <ac:link> xhtml node 에서는 다른 Space 의 문서를 가리키는 pageId 값이 포함되지 않았습니다. 이에 따라, pageId 를 이용한 정확한 url 링크를 만들지 못합니다.
수행할 과제
문제현상을 해결하는 방안을 도출하기 위해, 탐색과 조사, 분석을 수행합니다.
-
pageId 가 없이,
<ac:link>xhtml node 내부의 정보를 활용하여, url 을 생성하고 연결하는 것이 가능한지, 찾아봅니다. -
pageId 를 다른 입력 데이터에서 찾아봅니다. page.adf, page.html, page.v1.yaml, page.v2.yaml 등 포맷 데이터가 어떻게 다른지, 비교분석하고, 이를 활용할 수 있는 방안을 찾아봅니다.
과제의 결과
1단계: 데이터 포맷 분석 (2026-01-28)
조사 대상
테스트 케이스 1844969501 (문서 ID: "지원")의 다양한 포맷 파일을 분석하여 pageId 정보의 존재 여부를 확인했습니다.
발견 사항
page.xhtml (현재 변환에 사용 중)
- pageId 없음:
<ac:link>태그에는space-key와content-title만 포함되어 있습니다.
예시:
<ac:link><ri:page ri:space-key="QCP" ri:content-title="QueryPie Architecture (KO)" ri:version-at-save="6" /><ac:link-body>QueryPie Architecture</ac:link-body></ac:link>page.adf (Atlassian Document Format)
- ✅ pageId 포함: 완전한 Confluence URL이 포함되어 있으며, pageId를 추출할 수 있습니다.
예시:
{
"text": "QueryPie Architecture",
"type": "text",
"marks": [{
"type": "link",
"attrs": {
"href": "https://querypie.atlassian.net/wiki/spaces/QCP/pages/400064797"
}
}]
}page.v2.yaml (atlas_doc_format)
- ✅ pageId 포함: page.adf와 동일한 JSON 구조를 YAML로 포맷팅한 것으로, 완전한 URL 포함
page.v1.yaml (Confluence REST API v1 응답)
- ✅ pageId 포함:
body.view섹션의 HTML에data-linked-resource-id속성으로 pageId가 포함됨
예시:
<a href="/wiki/spaces/QCP/pages/400064797/QueryPie+Architecture+KO"
data-linked-resource-id="400064797"
data-linked-resource-version="6"
data-linked-resource-type="page">QueryPie Architecture</a>주요 발견
| 파일 포맷 | pageId 포함 여부 | 정보 형태 |
|---|---|---|
| page.xhtml | ❌ | space-key + content-title만 존재 |
| page.adf | ✅ | 완전한 URL (pageId 포함) |
| page.v2.yaml | ✅ | 완전한 URL (pageId 포함) |
| page.v1.yaml | ✅ | HTML 속성 (data-linked-resource-id) |
결론 및 다음 단계
- page.adf 또는 page.v2.yaml을 활용하면 정확한 pageId 기반 링크 생성이 가능합니다.
- 다음 조사 항목:
- 현재 변환 스크립트가 어떤 파일을 입력으로 사용하는지 확인
- page.adf 또는 page.v2.yaml을 대신 사용할 수 있는지 검토
- 또는 보조 데이터로 활용할 수 있는 방안 검토
2단계: 변환 스크립트 분석 및 매칭 전략 검증 (2026-01-28)
현재 변환 스크립트 구조
confluence_xhtml_to_markdown.py 분석 결과:
- 주 입력 파일:
page.xhtml(XHTML 콘텐츠 파싱) - 보조 데이터:
page.v1.yaml(현재는 현재 페이지의 제목과 경로 정보만 사용)
ADF 및 Confluence URL 구조 조사
Confluence URL 포맷 (공식 문서)
-
새로운 포맷 (Confluence 9.1+):
https://confluence.example.com/spaces/{SPACEKEY}/pages/{pageId}/{Page+Title}- pageId로 페이지를 식별
- 페이지 제목은 가독성을 위한 것
- 페이지 이름 변경 시 자동 리다이렉트
-
pageId 포맷:
http://confluence.example.com/pages/viewpage.action?pageId={pageId}
ADF 링크 구조 (공식 문서)
{
"type": "text",
"text": "Link Text",
"marks": [{
"type": "link",
"attrs": {
"href": "https://example.com/...",
"title": "Optional title"
}
}]
}매칭 전략 검증
전략 1: page.adf 사용
- ✅ 링크 텍스트를 기준으로 page.xhtml의
<ac:link-body>와 매칭 가능 ⚠️ 단,inlineCard노드는 링크 텍스트가 없어 매칭 실패 (5개 중 1개 실패)
테스트 결과:
✓ MATCHED: QueryPie Architecture -> 400064797
✓ MATCHED: Advanced Environment Setup -> 887947577
✓ MATCHED: Advanced Integration Guide -> 841449834
✗ NOT MATCHED: 릴리스 버전 별 문서 (inlineCard)
✓ MATCHED: Troubleshooting -> 920486841
전략 2: page.v1.yaml의 body.view 사용 ⭐ 권장
- ✅ 100% 매칭 성공
- ✅ 모든 링크 (일반 링크 + inlineCard)에 대해 링크 텍스트와 pageId 매핑 제공
테스트 결과:
✓ MATCHED: QueryPie Architecture -> 400064797
✓ MATCHED: Advanced Environment Setup -> 887947577
✓ MATCHED: Advanced Integration Guide -> 841449834
✓ MATCHED: 릴리스 버전 별 문서 -> 841351486
✓ MATCHED: Troubleshooting -> 920486841
구현 방안
권장 방안: page.v1.yaml body.view 활용
-
초기화 단계:
page.v1.yaml의body.viewHTML을 파싱하여 링크 매핑 생성def build_link_mapping(page_v1: PageV1) -> Dict[str, str]: """ Build a mapping of link text -> pageId from page.v1.yaml body.view Returns: Dict mapping link text to pageId """ link_map = {} view_html = page_v1.get('body', {}).get('view', {}).get('value', '') soup = BeautifulSoup(view_html, 'html.parser') for link in soup.find_all('a', {'data-linked-resource-id': True}): text = link.get_text() page_id = link.get('data-linked-resource-id', '') link_map[text] = page_id return link_map
-
변환 단계:
<ac:link>처리 시 링크 텍스트로 pageId 조회link_text = link_body # <ac:link-body> 내용 space_key = ri_page.get('space-key', '') # Try to find pageId from mapping page_id = link_mapping.get(link_text) if page_id: # Generate accurate URL with pageId href = f'https://querypie.atlassian.net/wiki/spaces/{space_key}/pages/{page_id}' elif space_key: # Fallback to space overview href = f'https://querypie.atlassian.net/wiki/spaces/{space_key}/overview' else: # Error case href = '#link-error'
-
URL 생성 전략:
- pageId 있음:
https://querypie.atlassian.net/wiki/spaces/{space_key}/pages/{page_id} - pageId 없음 + space_key 있음:
https://querypie.atlassian.net/wiki/spaces/{space_key}/overview(현재 구현) - 둘 다 없음:
#link-error(현재 구현)
- pageId 있음:
대안: page.adf 활용
- 대부분의 링크에 대해 작동
- inlineCard 처리를 위한 추가 로직 필요
- page.v1.yaml보다 복잡
결론
page.v1.yaml의 body.view HTML을 활용하는 방안이 가장 효과적입니다:
- ✅ 100% 매칭 성공률
- ✅ 현재 스크립트에서 이미 page.v1.yaml을 로드하므로 통합 용이
- ✅ 구현이 간단하고 명확
- ✅ 모든 링크 타입 (일반 링크, inlineCard) 지원
다음 단계
confluence_xhtml_to_markdown.py에 링크 매핑 빌드 함수 추가<ac:link>처리 로직에 pageId 조회 기능 통합- 테스트 케이스로 검증
- PR 생성
Metadata
Metadata
Assignees
Labels
No labels