簡體   English   中英

嘗試為我自己的XML樣式文件格式編寫解析器,並獲得FileNotFoundException,特別是我做錯了什么嗎?

[英]Attempting to write a parser for my own XML style file format, getting FileNotFoundException, is there anything in particular I'm doing wrong?

因此,基本上,我正在嘗試編寫一個2D骨骼動畫編輯器以及一個框架,以使其易於使用游戲中在編輯器中創建的相同動畫。 最大的問題是我以前沒有寫過XML解析器,所以我感覺自己可能做的事情完全錯誤,但是我不確定這是什么。

這是我格式的示例文件:

<skeleton name="skeleton1">

    <bones>
        <bone name="bone1" id="1" textureLoc="/imgs/test.png">
            <position>x,y</position>
            <rotation>float</rotation>
            <scale>float</scale>
        </bone>

        <bone name="bone2" id="2" textureLoc="/imgs/text2.png">
            <position>x,y</position>
            <rotation>float</rotation>
            <scale>float</scale>
        </bone>
    </bones>

    <animation name="anim1">
        <keyframe frameToPlay="1">
            <bone id="1" transPosition="x,y" transRotation="float" transScale="float">
            </bone>

            <bone id="2" transPosition="x,y" transRotation="float" transScale="float">
            </bone>
        </keyframe>

        <keyframe frameToPlay="50">
            <bone id="1" transPosition="x,y" transRotation="float" transScale="float">
            </bone>

            <bone id="2" transPosition="x,y" transRotation="float" transScale="float">
            </bone>
        </keyframe>
    </animation>

    <animation name="anim2">
        <keyframe frameToPlay="1">
            <bone id="1" transPosition="x,y" transRotation="float" transScale="float">
            </bone>

            <bone id="2" transPosition="x,y" transRotation="float" transScale="float">
            </bone>
        </keyframe>

        <keyframe frameToPlay="50">
            <bone id="1" transPosition="x,y" transRotation="float" transScale="float">
            </bone>

            <bone id="2" transPosition="x,y" transRotation="float" transScale="float">
            </bone>
        </keyframe>
    </animation>
</skeleton>



如果它使我的代碼更易於理解,這是對我組織此系統的方式的描述:

AnimationSystem – Management interface for all animations in game, handles updating of each skeleton
--List of skeletons
---Skeletons represent each object
--Update method that updates each skeleton with the game’s current frame
Animation
--List of keyframes
--List of frames, in ascending order, pulled from the list of keyframes
---Order index in list corresponds to order index in list of keyframes
---Should help to speed things up a little bit, no need to search every keyframe to determine which one has a frame value matching the one that is currently needed.
---Will be determined by a set up method after assets are loaded, but before the animation can be used.
--Method to return a keyframe that corresponds to a frame passed to the method
Skeleton
--List of animations
--List of bones
--Value to hold the currently selected animation
--Value to hold the current frame in the game
--Value to hold the name of the skeleton
--Upon moving to a new frame, searches currently selected animation’s list of frames to see if a keyframe should be “played” this frame. If a keyframe exists that should be played at this frame, it should go through each bone in its list of bones, and set the properties of each bone to the properties listed in the keyframe according to the bone’s id.
Bone
--Value to hold the stationary position
--Value to hold the stationary rotation
--Value to hold the stationary scale
--Value to hold the transformed position
--Value to hold the transformed rotation
--Value to hold the transformed scale
--Image value that holds the texture of the bone
--Value to hold the id of the bone within its skeleton
--Value to hold the name of the bone (Used in the editor)
--Method that takes 3 values (position, rotation and scale in that order) and set’s its own transformed pos, rot and scale values to those passed in.
Keyframe
--List of scale values
--List of position values
--List of rotation values
--List of bone ids
---Index of bone id in list matches up to index in scale, position and rotation lists so that the properties can be associated with the bone
--Time value at which the keyframe will be played
--Method to return the scale value of a bone as determined by the bone id passed in
--Method to return the position value of a bone as determined by the bone id passed in
--Method to return the rotation value of a bone as determined by the bone id passed in



我為嘗試解析此代碼而編寫的關聯方法如下:

public static Skeleton parseSkeletonFile(String location) throws FileNotFoundException, IOException
    {
        try
        {
            Skeleton skelToReturn = null;

            File fileToLoad = new File(location);

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fileToLoad);

            doc.getDocumentElement().normalize();

            NodeList skelList = doc.getElementsByTagName("skeleton");

            for (int counter = 0; counter < skelList.getLength(); counter++)
            {
                Node skelNode = skelList.item(counter);

                Element skelElement = (Element)skelNode;

                skelToReturn = new Skeleton(skelElement.getAttribute("name"));

                NodeList allNodes = skelNode.getChildNodes();

                for (int counter2 = 0; counter2 < allNodes.getLength(); counter2++)
                {
                    Node currentNode = allNodes.item(counter2);

                    if (currentNode.getNodeName() == "bones")
                    {
                        NodeList bonesNL = currentNode.getChildNodes();

                        for (int counter3 = 0; counter3 < bonesNL.getLength(); counter3++)
                        {
                            Node currentBone = bonesNL.item(counter3);
                            Element currentBoneE = (Element)currentBone;

                            Bone bone = new Bone(
                                    currentBoneE.getAttribute("name"),
                                    new Point(
                                        Float.valueOf(currentBoneE.getElementsByTagName("position").item(0).getTextContent().split(",")[0]),
                                        Float.valueOf(currentBoneE.getElementsByTagName("position").item(0).getTextContent().split(",")[1])
                                        ),
                                    Float.valueOf(currentBoneE.getElementsByTagName("rotation").item(0).getTextContent()),
                                    Float.valueOf(currentBoneE.getElementsByTagName("scale").item(0).getTextContent()),
                                    Integer.valueOf(currentBoneE.getAttribute("id"))
                                    );



                            bone.setImage(new Image(currentBoneE.getAttribute("textureLoc")));

                            skelToReturn.bones.add(bone);
                        }
                    }

                    if (currentNode.getNodeName() == "animation")
                    {
                        NodeList animsNL = currentNode.getChildNodes();

                        for (int counter4 = 0; counter4 < animsNL.getLength(); counter4++)
                        {
                            Node currentAnim = animsNL.item(counter4);
                            Element currentAnimE = (Element)currentAnim;

                            Animation animation = new Animation(currentAnimE.getAttribute("name"));

                            NodeList keyframesNL = currentAnim.getChildNodes();

                            for (int counter5 = 0; counter5 < keyframesNL.getLength(); counter5++)
                            {
                                Node currentKeyframe = keyframesNL.item(counter5);
                                Element currentKeyframeE = (Element)currentKeyframe;

                                Keyframe keyframe = new Keyframe(Integer.valueOf(currentKeyframeE.getAttribute("frameToPlay")));

                                NodeList kfBonesNL = currentKeyframe.getChildNodes();

                                for (int counter6 = 0; counter6 < kfBonesNL.getLength(); counter6++)
                                {
                                    Node currentBoneTrans = kfBonesNL.item(counter6);
                                    Element currentBoneTransE = (Element)currentBoneTrans;

                                    keyframe.boneIDs.add(Integer.valueOf(currentBoneTransE.getAttribute("id")));
                                    keyframe.positions.add(new Point(Float.valueOf(currentBoneTransE.getAttribute("transPosition").split(",")[0]), Float.valueOf(currentBoneTransE.getAttribute("transPosition").split(",")[1])));
                                    keyframe.rotations.add(Float.valueOf(currentBoneTransE.getAttribute("transRotation")));
                                    keyframe.scales.add(Float.valueOf(currentBoneTransE.getAttribute("transScale")));
                                }
                                animation.keyframes.add(keyframe);
                                animation.frames.add(keyframe.getTimeToBePlayed());
                            }

                            skelToReturn.animations.add(animation);
                            skelToReturn.animationNames.add(animation.name);
                        }
                    }
                }
            }
            if (skelToReturn != null)
                return skelToReturn;
            else
                return null;
        } catch (Exception e)
        {
            e.printStackTrace();
        }

        return null;
    }



這是我用來按原樣測試解析器的代碼片段:

AnimationSystem animator = new AnimationSystem();
        try {
            skeleton = animator.parseSkeletonFile(getClass().getResource("SkeletonTest.xml").getPath());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (skeleton != null)
        {
            System.out.println(skeleton.name);
        }


這是使用Slick2D構建的簡單游戲的init方法。 我嘗試加載的文件SkeletonTest.xml與調用解析方法的類位於同一包中。 它的內容很簡單:

<skeleton name="TestSkeleton">

</skeleton>



這是我整體收到的錯誤消息:

java.io.FileNotFoundException: D:\Eclipse%20Workspace\2dSkeletalAnimator\bin\org\jason\animatorTests\SkeletonTest.xml (The system cannot find the path specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at sun.net.www.protocol.file.FileURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
    at org.jason.skeletalanimator.AnimationSystem.parseSkeletonFile(AnimationSystem.java:42)
    at org.jason.animatorTests.AnimatorTest1.init(AnimatorTest1.java:32)
    at org.newdawn.slick.AppGameContainer.setup(AppGameContainer.java:433)
    at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:357)
    at org.jason.animatorTests.AnimatorTest1.main(AnimatorTest1.java:65)



很抱歉,這個問題有點籠統,而且需要一定的背景信息,但是我已經嘗試了幾乎所有方法來使此方法在不重寫解析方法主體的情況下起作用。 我不想再經歷那一團糟。 因此,我希望有更多從XML樣式文件加載數據的經驗的人可以在這里為我提供幫助。 我要感謝提前給我一些時間的人。

一個問題是您試圖從類路徑條目中獲取File getPath()方法返回文件URL,而不是文件路徑。 然后,您嘗試像加載文件路徑一樣加載該文件,這會導致問題。

如果要使用為您提供InputStream getClass().getResourceAsStream()會容易InputStream

除了傳遞location ,還可以將InputStream傳遞給parseSkeleton方法,然后更改為使用DocumentBuilder#parse(InputStream)

使用InputStream的另一個好處是,如果將類打包到JAR文件中,則仍然可以加載資源(您將無法獲得指向JAR內部的有效File路徑)。 或者您的骨架定義可以來自任何其他InputStream ,例如網絡等。

java.io.FileNotFoundException:D:\\ Eclipse%20Workspace \\ 2dSkeletalAnimator \\ bin \\ org \\ jason \\ animatorTests \\ SkeletonTest.xml(系統找不到指定的路徑)

您的路徑上有一個空間。 這就是問題。 注意%20。 我看不到它的編碼位置,但是您應該在調用之前解碼文件路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM