From 5c62e57cfbecf2bd82e490ff685a759dfb8ad1bc Mon Sep 17 00:00:00 2001 From: dragdra Date: Fri, 13 Jun 2025 17:03:43 +0900 Subject: [PATCH] =?UTF-8?q?2505=ED=9A=8C=20=EC=98=A4=ED=94=84=EB=8B=9D,=20?= =?UTF-8?q?=EB=8F=99=EC=98=81=EC=83=81=20=EC=9E=90=EB=A7=89=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=EA=B8=B0=EC=A4=80=20=EB=B3=80=EA=B2=BD=20[2-10,11,28,?= =?UTF-8?q?29]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 00_DIC_2505B_TEST.xlsx | Bin 0 -> 28109 bytes 250529_DIC_2505C_채점결과.xlsx | Bin 156147 -> 22815 bytes DIC_2505A.json | 36 ++--- DIC_2505B.json | 63 +++++---- DIC_2505C.json | 61 +++++---- psdExport_2.js | 244 ++++++++++++++++++++++++++++----- z.xbook | 2 +- 7 files changed, 296 insertions(+), 110 deletions(-) create mode 100644 00_DIC_2505B_TEST.xlsx diff --git a/00_DIC_2505B_TEST.xlsx b/00_DIC_2505B_TEST.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1b0f55a30eadfff6f452f034412e12456137745c GIT binary patch literal 28109 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 literal 0 HcmV?d00001 diff --git a/250529_DIC_2505C_채점결과.xlsx b/250529_DIC_2505C_채점결과.xlsx index 2e10673a652e0ccf8f52a1dffbbb9ddceeca3919..300db88349ee667fc394af7183c2c4cf669f38e3 100644 GIT binary patch literal 22815 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 Jv>~|n{{R$d5S#!2 literal 156147 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자막>시작시간 문항의 정답을 작성", "videoStartTime": 170, "openingStartTime": 0, "1": { @@ -193,7 +194,7 @@ "이미지2.jpg" ], "point": 4, - "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5이하인 경우는 제외한다." + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." }, "2": { "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", @@ -205,7 +206,7 @@ "desc": "100당 1배속 / 130 = 1.3배속" }, "3": { - "ele": "//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']", "type": "startEnd", "media": "동영상.mp4", "value": { @@ -216,19 +217,20 @@ "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." }, "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)]//CRFilter[@ID='168'][@VID100='0.80000001'][@VID102='10']", - "type": "", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", "value": { "ID": "168", - "VID100": "0.80000001", - "VID102": "10" + "VID102": "10", + "VID100": "0.80000001" }, "point": 3, - "desc": "/CROASTERP/CRTrackArr/CRVideoTrackArr/CRTrackList[1]/CRTrackClip[1]/CRFilterArr/CRFilter 요소의 속성값 확인" + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" }, "5": { - "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", - "ele2": "//CRCUnitArr[@Name='{search}']/@Name", + "ele": "//CRCUnitArr[@Name='{search}']/@Name", + "ele2": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", "type": "video", "value": "모래 촉감 놀이", "search": "모래 촉감 놀이", @@ -270,19 +272,17 @@ "point": 2 }, "10": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele": "{search}", "search": "모래 촉감 놀이", - "type": "video", + "type": "videoStartTime", "value": 170, "point": 2 }, "11": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele": "{search}", "search": "모래 촉감 놀이", - "type": "video", - "value": "150", + "type": "videoLength", + "value": 150, "point": 2 }, "12": { @@ -438,7 +438,7 @@ }, "28": { "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/preceding-sibling::CRTrackClip/@Length)", "search": "자연 놀이터 (Nature Playground)", "type": "opening", "value": 0, @@ -446,7 +446,7 @@ }, "29": { "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={textClipIndex}]/@Length", "search": "자연 놀이터 (Nature Playground)", "type": "opening", "value": "120", diff --git a/DIC_2505B.json b/DIC_2505B.json index 7c62061..cf1e9e2 100644 --- a/DIC_2505B.json +++ b/DIC_2505B.json @@ -181,40 +181,52 @@ } }, "2": { + "desc": "videoStartTime 항목은 동영상파일>자막>시작시간 문항의 정답을 작성", "videoStartTime": 170, "openingStartTime": 0, "1": { - "ele": "//CRClipArr/CRClip[position() = //CRTrackList[1]/CRTrackClip/@ClipIndex]/@Path", - "type": "array", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", + "type": "mediaOrder", "value": [ "동영상.mp4", "이미지2.jpg", "이미지3.jpg", "이미지1.jpg" ], - "point": 4 + "point": 4, + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." }, "2": { - "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1][@Speed='120']", - "point": 2 + "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", + "type": "oneAnswer", + "value": { + "speed": "120" + }, + "point": 2, + "desc": "100당 1배속 / 130 = 1.3배속" }, "3": { - "ele": "count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)", - "type": "startend", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']", + "type": "startEnd", + "media": "동영상.mp4", + "value": { "start": "0", - "end": "380", - "point": 2 + "end": "360" + }, + "point": 2, + "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." }, "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)]//CRFilter[@ID='70'][@VID100='30'][@VID101='20']", - "type": "", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", "value": { "ID": "70", "VID100": "30", "VID101": "20" }, "point": 3, - "desc": "/CROASTERP/CRTrackArr/CRVideoTrackArr/CRTrackList[1]/CRTrackClip[1]/CRFilterArr/CRFilter 요소의 속성값 확인" + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" }, "5": { "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", @@ -260,19 +272,17 @@ "point": 2 }, "10": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele": "{search}", "search": "청량하고 시원한 폭포", - "type": "video", + "type": "videoStartTime", "value": 170, "point": 2 }, "11": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele": "{search}", "search": "청량하고 시원한 폭포", - "type": "video", - "value": "150", + "type": "videoLength", + "value": 150, "point": 2 }, "12": { @@ -427,19 +437,18 @@ "point": 3 }, "28": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele":"{search}", "search": "전통 공원 (Traditional Park)", - "type": "opening", + "type": "openingStartTime", "value": 0, - "point": 2 + "point": 2, + "desc": "오프닝자막의 시작시간 value 속성만 수정" }, "29": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele":"{search}", "search": "전통 공원 (Traditional Park)", - "type": "opening", - "value": "120", + "type": "openingLength", + "value": 120, "point": 2 }, "30": { diff --git a/DIC_2505C.json b/DIC_2505C.json index ea6a3f4..7bf210f 100644 --- a/DIC_2505C.json +++ b/DIC_2505C.json @@ -186,37 +186,48 @@ "videoStartTime": 160, "openingStartTime": 0, "1": { - "ele": "//CRClipArr/CRClip[position() = //CRTrackList[1]/CRTrackClip/@ClipIndex]/@Path", - "type": "array", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[not(@Length<='5' and @ClipLength='-1')]/@ClipIndex", + "type": "mediaOrder", "value": [ "동영상.mp4", "이미지2.jpg", "이미지1.jpg", "이미지3.jpg" ], - "point": 4 + "point": 4, + "desc": "비디오1 트랙에 있는 클립의 ClipIndex값을 기준으로 CRClipArr에서 Path값을 가져와서 정답 채점, 클립의 ClipIndex값이 -1인 경우와 길이가 5프레임 이하인 경우는 제외한다." }, "2": { - "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1][@Speed='130']", - "point": 2 + "ele": "/CROASTERP/CRTrackArr[1]/CRVideoTrackArr[1]/CRTrackList[1]/CRTrackClip[1]/@Speed", + "type": "oneAnswer", + "value": { + "speed": "130" + }, + "point": 2, + "desc": "100당 1배속 / 130 = 1.3배속" }, "3": { - "ele": "count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)", - "type": "startend", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']", + "type": "startEnd", + "media": "동영상.mp4", + "value": { "start": "0", - "end": "350", - "point": 2 + "end": "350" + }, + "point": 2, + "desc": "시작시간과 재생시간 정답값 입력, 3번문항은 '동영상.mp4' 클립의 길이를 확인하는 문항이므로 media는 수정할 필요가 없다." }, "4": { - "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='동영상.mp4']/preceding-sibling::*)]//CRFilter[@ID='56'][@VID100='45'][@VID101='60']", - "type": "", + "ele": "//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter", + "type": "effect", + "media": "동영상.mp4", "value": { "ID": "56", "VID100": "45", "VID101": "60" }, "point": 3, - "desc": "/CROASTERP/CRTrackArr/CRVideoTrackArr/CRTrackList[1]/CRTrackClip[1]/CRFilterArr/CRFilter 요소의 속성값 확인" + "desc": "value값의 키값(VID___)은 이펙트의 속성종류에 따라 변경되므로 채점기준표작성시 확인 필요" }, "5": { "ele": "//CROwneUnit[{subtitleIndex}]/CRCUnitArr/@Name", @@ -262,19 +273,17 @@ "point": 2 }, "10": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele": "{search}", "search": "연못의 연잎들", - "type": "video", - "value": 160, + "type": "videoStartTime", + "value": 170, "point": 2 }, "11": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele": "{search}", "search": "연못의 연잎들", - "type": "video", - "value": "120", + "type": "videoLength", + "value": 120, "point": 2 }, "12": { @@ -427,19 +436,17 @@ "point": 3 }, "28": { - "ele": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/preceding-sibling::CRTrackClip/@Length)", - "ele2": "sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/preceding-sibling::CRTrackClip/@Length)", + "ele":"{search}", "search": "초록빛 이파리들 Green leaves", - "type": "opening", + "type": "openingStartTime", "value": 0, "point": 2 }, "29": { - "ele": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][{subtitleOrder}]/@Length", - "ele2": "//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@ClipIndex='-1')][@ClipIndex={clipIndex}]/@Length", + "ele":"{search}", "search": "초록빛 이파리들 Green leaves", - "type": "opening", - "value": "120", + "type": "openingLength", + "value": 120, "point": 2 }, "30": { diff --git a/psdExport_2.js b/psdExport_2.js index 88708db..8b05282 100644 --- a/psdExport_2.js +++ b/psdExport_2.js @@ -15,8 +15,8 @@ const examRound = '2505'; const dic_or_dpi = 'DIC' // const dic_or_dpi = 'DPI' const examTypes = [ - 'A', - // 'B', + // 'A', + 'B', // 'C', // 'D' ]; @@ -172,7 +172,6 @@ outputExcelFiles.forEach((outputFile, index) => { // scoring.json 파일 내에 있는 type에 따라 비교하는 방식이 달라짐 // 채점 결과를 scoringResultList 배열에 저장 function getGmepScore(gmepData, scoringJson, index) { - function compareAndScore(userAnswer, rightAnswer, point, key, scoringResult) { let score = 0; @@ -192,9 +191,6 @@ function getGmepScore(gmepData, scoringJson, index) { scoringResult[key] = score; return score; } - function getMediaOrderbyClipIndex(gmepXmlDoc, clipIndex) { - - } const gmepXmlDoc = gmepData; const scoringResult = {}; @@ -207,6 +203,116 @@ function getGmepScore(gmepData, scoringJson, index) { // 채점기준표 문항별 분류 for (const key in scoringData) { + function getClipIndexByMediaPath(mediaName) { + // CRClipArr/CRClip 요소의 Path속성 리스트를 구함 + // 모션 클립 이미지도 고려해 처리 + const mediaPathList = xpath.select("//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path", gmepXmlDoc); + + // "동영상.mp4"의 clipIndex를 구함 + const videoClipIndex = mediaPathList.findIndex(mediaPath => mediaPath.value === mediaName); + let xpathList = [ele, ele2]; + xpathList = xpathList.map(e => e ? e + .replace(/{videoClipIndex}/g, videoClipIndex) + : e + ); + [ele, ele2] = xpathList; + // clipIndex가 -1이면 해당 미디어가 존재하지 않는 것 + + return videoClipIndex; + } + + // 자막 텍스트로 자막클립인덱스 반환 + function getClipIndexByText(text) { + const crOwneUnits = xpath.select(`//CROwneUnitArr/CROwneUnit`, gmepXmlDoc); + + let subtitleClipIndex = null; + // 자막 텍스트와 일치하는 요소의 인덱스를 반환 + for (let i = 0; i < crOwneUnits.length; i++) { + const crcUnitArr = xpath.select1('.//CRCUnitArr', crOwneUnits[i]); + if (crcUnitArr && crcUnitArr.getAttribute('Name') === text) { + subtitleClipIndex = i; + break; + } + } + console.log('🟢 자막 텍스트로 검색한 CROwneUnit 인덱스 : ', subtitleClipIndex); + return subtitleClipIndex; + } + + function getClipIndexByOrder(order) { + // 자막의 갯수가 2개 이상 (오프닝과 동영상 자막이 있을 경우) + // 앞은 오프닝 뒤는 동영상 자막으로 판단 + // crTrackClips[0] : 오프닝 자막 + // crTrackClips[1] : 동영상 자막 + const crOwneUnits = xpath.select(`//CROwneUnitArr/CROwneUnit`, gmepXmlDoc); + const crTrackClips = xpath.select("//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[not(@Type='0') and not(@ClipIndex='-1')]", gmepXmlDoc); + let subtitleClipIndex = null; + if (subtitleClipIndex === null && crOwneUnits.length >= 2) { + // if (crOwneUnits.length >= 2) { + for (let i = 0; i < crTrackClips.length; i++) { + if ((order - 1) === i) { + subtitleClipIndex = parseInt(crTrackClips[i].getAttribute('ClipIndex'), 10); + break; + } + } + } + console.log('🟡 자막 순서로 검색한 CROwneUnit 인덱스 : ', subtitleClipIndex); + return subtitleClipIndex; + } + + // 자막들의 시작 시간을 가지는 리스트에서 + // 구하고자 하는 영상의 시작시간(startTime)과 일치하는 시간이 있다면 인덱스를 가져와 + // 자막의 인덱스를 구함 + function getCilpIndexByStartTime(startTime) { + const crTrackClips = xpath.select("//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip", gmepXmlDoc); + const subtitleStartTimeList = getSubtitleStartTime(); + const startTimeIndex = subtitleStartTimeList.findIndex(value => value === startTime); + + let subtitleClipIndex = null; + for (let i = 0; i < crTrackClips.length; i++) { + if (parseInt(crTrackClips[i].getAttribute('ClipIndex'), 10) == -1) { + continue; + } + const clipIndex = parseInt(crTrackClips[i].getAttribute('ClipIndex'), 10); + if (startTimeIndex === i) { + subtitleClipIndex = clipIndex; + break; + } + } + console.log('🟠 자막 시작시간으로 검색한 CROwneUnit 인덱스 : ', subtitleClipIndex); + return subtitleClipIndex; + } + + // 영상내 존재하는 자막과 자막사이 공백의 시작시간 리스트를 구함 + function getSubtitleStartTime() { + const trackClips = xpath.select(`//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip`, gmepXmlDoc); + + let cumulativeLengths = []; + let total = 0; + + for (let i = 0; i < trackClips.length; i++) { + const length = parseInt(trackClips[i].getAttribute('Length'), 10); + + cumulativeLengths.push(total); + total += length; + } + + console.log("🔵 자막 구간 시작시간 : ", cumulativeLengths); + return cumulativeLengths; + } + + function getCrtrackClipIndex(clipIndex) { + const crTrackClips = xpath.select(`//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip`, gmepXmlDoc); + + let index = null; + for (let i = 0; crTrackClips.length; i++) { + if (clipIndex == parseInt(crTrackClips[i].getAttribute('ClipIndex'), 10)) { + index = i; + break; + } + } + return index; + } + let ele = scoringData[key].ele; let ele2 = scoringData[key].ele2; let ele3 = scoringData[key].ele3; @@ -226,10 +332,16 @@ function getGmepScore(gmepData, scoringJson, index) { // xpath 전처리 const trackClipNode = getTrackClipNode(gmepXmlDoc, type, videoStartTime, openingStartTime); const subtitleIndex = trackClipNode ? parseInt(trackClipNode.getAttribute('ClipIndex'), 10) + 1 : null; - const clipIndex = getClipIndexBySubtitle(gmepXmlDoc, search); - // const subtitleOrder = type === 'video' ? 2 : type === 'opening' ? 1 : null; - // 2503회 문제오류 처리를 위한 임시 변경 - const subtitleOrder = type === 'video' ? 2 : type === 'opening' ? 1 : null; + const textClipIndex = getTextClipIndex(gmepXmlDoc, search); + const typeToOrderMap = { + opening: 1, + openingStartTime: 1, + openingLength: 1, + video: 2, + videoStartTime: 2, + videoLength: 2, + }; + const subtitleOrder = typeToOrderMap[type] ?? null; const startTime = type === 'video' ? videoStartTime : type === 'opening' ? openingStartTime : null; let xpathList = [ele, ele2, ele3, existEle]; @@ -237,17 +349,12 @@ function getGmepScore(gmepData, scoringJson, index) { .replace(/{subtitleIndex}/g, subtitleIndex) .replace(/{subtitleOrder}/g, subtitleOrder) .replace(/{startTime}/g, startTime) - .replace(/{clipIndex}/g, clipIndex) + .replace(/{textClipIndex}/g, textClipIndex) .replace(/{image}/g, image) : e ); [ele, ele2, ele3, existEle] = xpathList; - // [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{subtitleIndex}/g, subtitleIndex)); - // [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{subtitleOrder}/g, subtitleOrder)); - // [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{startTime}/g, startTime)); - // [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.replace(/{clipIndex}/g, clipIndex)); - // search 값이 undefined 아니면 ele의 {search}부분을 search로 치환 /** * JSON파일 곰믹스 5번문항/22번 문항 @@ -260,11 +367,9 @@ function getGmepScore(gmepData, scoringJson, index) { let result = findSimilarString(gmepXmlDoc, search, 0.8); if (result !== null) { result = result.replace(/"/g, "'"); - [ele, ele2, ele3, existEle] - = [ele, ele2, ele3, existEle].map(e => e?.replace(/{search}/g, result)); + [ele, ele2, ele3, existEle] = [ele, ele2, ele3, existEle].map(e => e?.replace(/{search}/g, result)); } else { - [ele, ele2, ele3] - = [ele, ele2, ele3].map(e => e?.includes('{search}') ? null : e); + [ele, ele2, ele3] = [ele, ele2, ele3].map(e => e?.includes('{search}') ? null : e); } } @@ -305,20 +410,24 @@ function getGmepScore(gmepData, scoringJson, index) { // 미디어의 인덱스 순서 const clipIndexOrder = xpath.select(ele, gmepXmlDoc); + clipIndexOrder.forEach((clipIndex) => { CRClipIndex = parseInt(clipIndex.value, 10) + 1; // XPath는 1-based index를 사용 // 인덱스 순서에 따른 CRClip 요소의 Path를 찾기 const mediaPath = xpath.select1(`//CRClipArr/CRClip[${CRClipIndex}]/@Path`, gmepXmlDoc); + // 만약 CRClip 요소가 motion clip인 경우 CRCUnitArr의 Path를 찾기 if (mediaPath == null) { const motionClipPath = xpath.select1(`//CRClipArr/CRClip[${CRClipIndex}]/CRCUnitArr/@Path`, gmepXmlDoc); if (motionClipPath !== null) { - mediaOrderList.push(motionClipPath.value); + const fileName = path.basename(motionClipPath.value); + mediaOrderList.push(fileName); } } else if (mediaPath != null) { - mediaOrderList.push(mediaPath.value); + const fileName = path.basename(mediaPath.value); + mediaOrderList.push(fileName); } }); const userAnswer = mediaOrderList; @@ -326,38 +435,99 @@ function getGmepScore(gmepData, scoringJson, index) { } else if (type == "startEnd") { - // CRClipArr/CRClip 요소의 Path속성 리스트를 구함 - // 모션 클립 이미지도 고려해 처리 - const mediaPathList = xpath.select("//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path", gmepXmlDoc); + const videoClipIndex = getClipIndexByMediaPath(media); - // "동영상.mp4"의 clipIndex를 구함 - let clipIndex = mediaPathList.findIndex(mediaPath => mediaPath.value === media); - // clipIndex가 -1이면 해당 미디어가 존재하지 않는 것 - if (clipIndex === -1) { + // 해당 미디어가 없을경우 clipIndex값 -1 + if (videoClipIndex == -1) { scoringResult[key] = 0; continue; } - else { // //CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='동영상.mp4'] 요소를 찾음 - const trackClipNode = xpath.select1(`//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='${clipIndex}']`, gmepXmlDoc); - if (!trackClipNode) { + const CRTrackClipNode = xpath.select1(ele, gmepXmlDoc); + if (!CRTrackClipNode) { scoringResult[key] = 0; continue; } else { // CRTrackClip 요소의 Pos(시작시간)과 Length(재생길이)를 구함 - const pos = xpath.select1('@Pos', trackClipNode); - const length = xpath.select1('@Length', trackClipNode); + const pos = xpath.select1('@Pos', CRTrackClipNode); + const length = xpath.select1('@Length', CRTrackClipNode); const userAnswer = { start: pos.value, end: length.value } totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); } } + } + else if (type == "effect") { + const videoClipIndex = getClipIndexByMediaPath(media); + if (videoClipIndex == -1) { + scoringResult[key] = 0; + continue; + } + else { + //CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='{videoClipIndex}']//CRFilter + const CRFilterNode = xpath.select1(ele, gmepXmlDoc); + if (!CRFilterNode) { + scoringResult[key] = 0; + continue; + } + else { + const userAnswer = {} + const attributes = CRFilterNode.attributes; - + // rightAnswer의 key값을 순회하면서 + // CRFilterNode의 속성명과 일치하는 값을 userAnswer에 저장 + // for (const [keyName, expectedValue] of Object.keys(rightAnswer)) { + for (const keyName of Object.keys(rightAnswer)) { + const attr = attributes.getNamedItem(keyName); + userAnswer[keyName] = attr ? attr.value : null; + } + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + } + } } + else if (type === 'openingStartTime' || type === 'openingLength' + || type === 'videoStartTime' || type === 'videoLength') { + // 자막의 정보를 이용해 CROwneUnit의 인덱스를 구함 + // 1. 텍스트 + // 2. 순서 + // 3. 시작시간 + const indexByText = getClipIndexByText(ele); + const indexByOrder = getClipIndexByOrder(subtitleOrder); + + if (type.includes('opening')) time = openingStartTime; + else if (type.includes('video')) time = videoStartTime; + else time = null; + const indexByStartTime = getCilpIndexByStartTime(time); + + // 1, 2, 3순으로 자막을 찾음 + const index = indexByText ?? indexByOrder ?? indexByStartTime; + if (index != null) { + // 자막 시작시간 + if (type.includes('StartTime')) { + const crtrackClipIndex = getCrtrackClipIndex(index) + const startTimeList = getSubtitleStartTime(); + const startTime = startTimeList[crtrackClipIndex]; + userAnswer = startTime; + } + + // 자막 길이 + else if (type.includes('Length')) { + const crtrackClipIndex = getCrtrackClipIndex(index) + 1 // XML 1-based index + const clipLength = xpath.select1(`//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[${crtrackClipIndex}]/@Length`, gmepXmlDoc); + + userAnswer = parseInt(clipLength.value, 10); + } + } + else { + userAnswer = null; + } + + totalScore += compareAndScore(userAnswer, rightAnswer, point, key, scoringResult); + } + else if (type == "color") { const result = xpath.select(ele, gmepXmlDoc); @@ -468,7 +638,7 @@ function getGmepScore(gmepData, scoringJson, index) { // 찾으려는 자막이 존재하지 않는 경우 // (2-28) 문항의 경우 오프닝 자막이 없어도 xpath구문의 sum함수 결과값이 0이 반환되는것을 방지 - if (trackClipNode === undefined && clipIndex === null) { + if (trackClipNode === undefined && textClipIndex === null) { scoringResult[key] = 0; continue; } @@ -703,7 +873,7 @@ function getTrackClipNode(xmlDoc, type, videoStartTime, openingStartTime) { * 1. 자막 텍스트의 유사도를 판별 * 2. 자막텍스트와 일치하는 자막요소(CROWneUnit)의 순서를 구함 */ -function getClipIndexBySubtitle(xmlDoc, search) { +function getTextClipIndex(xmlDoc, search) { // 1. search값이 일치하지 않는 경우 : count가 0이 되어 @ClipIndex = 0 / CROwneUnit[1]을 가리킴 [오류] // 2. search값이 일치하는 경우 // 1) search값이 CROwneUnit[1]이면 : preceding-sibling::CROwneUnit이 없어서 @ClipIndex = 0 / CROwneUnit[1]을 가리킴 [정상] diff --git a/z.xbook b/z.xbook index cf45aef..80492a9 100644 --- a/z.xbook +++ b/z.xbook @@ -1 +1 @@ -[{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Tracking']]/Effects/Item/Name/@value"},{"kind":2,"language":"xpath","value":"sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[@ClipIndex=0]/preceding-sibling::CRTrackClip/@Length)"},{"kind":2,"language":"xpath","value":"//CROwneUnit/CRCUnitArr[@Name=\"아름다운 꽃 축제 (Happy Flower Festival)\"]/@Name"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value\r\n"},{"kind":2,"language":"xpath","value":"//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='이미지3.jpg']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='이미지3.jpg']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']"},{"kind":2,"language":"xpath","value":"//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex='1']"},{"kind":2,"language":"xpath","value":"//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path"}] \ No newline at end of file +[{"kind":2,"language":"xpath","value":"//Layer[Name[@value='Tracking']]/Effects/Item/Name/@value"},{"kind":2,"language":"xpath","value":"sum(//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[@ClipIndex=0]/preceding-sibling::CRTrackClip/@Length)"},{"kind":2,"language":"xpath","value":"//CROwneUnit/CRCUnitArr[@Name=\"아름다운 꽃 축제 (Happy Flower Festival)\"]/@Name"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item[EffectData/{option}]/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value"},{"kind":2,"language":"xpath","value":"//Layer[Name[@value='{layer}']]/Effects/Item/Name/@value | //Layer[Name[@value='{layer}']]/Effects/Item/EffectData/{option}/@value\r\n"},{"kind":2,"language":"xpath","value":"//CRTransFilter[@ClipIndex=count(//CRTrackList[@Name='비디오1']/CRTrackClip[@ClipIndex=count(//CRClip[@Path='이미지3.jpg']/preceding-sibling::CRClip | //CRClip[@Type='11']/CRCUnitArr[@Path='이미지3.jpg']/../preceding-sibling::CRClip)][1]/preceding-sibling::CRTrackClip)][@Type='2']/@*[name()='ID' or name()='Range' or name()='Type']"},{"kind":2,"language":"xpath","value":"//CRTrackList[@Name='텍스트' or @Name='비디오2']/CRTrackClip[1]/@Length"},{"kind":2,"language":"xpath","value":"//CRClipArr/CRClip[@Type='11']/CRCUnitArr/@Path | //CRClipArr/CRClip[not(@Type='11')]/@Path"}] \ No newline at end of file