XMLPath от ant с использованием XMLTasks не может совпадать, если XML-файл имеет элементы в разных пространствах имен - PullRequest
2 голосов
/ 21 февраля 2012

Я пытаюсь получить какое-то соответствие, используя XMLTasks, чтобы заменить некоторые значения в XML-файле, но оно продолжает давать сбой из-за отсутствия соответствия.Используя другие инструменты, он говорит, что мой xpath правильный, но я не могу понять, в чем дело.

Вот файл, который я ищу:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
    <type>org.netbeans.modules.apisupport.project</type>
    <configuration>
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
            <code-name-base>simple.server.extension.cardgame</code-name-base>
            <suite-component/>
            <module-dependencies>
                <dependency>
                    <code-name-base>marauroa.lib</code-name-base>
                    <build-prerequisite/>
                    <compile-dependency/>
                    <run-dependency>
                        <release-version>3</release-version>
                        <specification-version>8</specification-version>
                    </run-dependency>
                </dependency>
                <dependency>
                    <code-name-base>simple.server.lib</code-name-base>
                    <build-prerequisite/>
                    <compile-dependency/>
                    <run-dependency>
                        <release-version>0-1</release-version>
                        <specification-version>0.2</specification-version>
                    </run-dependency>
                </dependency>
            </module-dependencies>
            <public-packages>
                <package>dreamer.card.game</package>
                <package>dreamer.card.game.model.events</package>
                <package>dreamer.card.game.price</package>
                <package>dreamer.card.game.storage</package>
                <package>simple.server.extension</package>
                <package>simple.server.extension.card</package>
            </public-packages>
            <class-path-extension>
                <runtime-relative-path>ext/extension/x.jar</runtime-relative-path>
                <binary-origin>../../Simple Marauroa Java/Card Game Extension/dist/x.jar</binary-origin>
            </class-path-extension>
            <class-path-extension>
                <runtime-relative-path>ext/extension/y.jar</runtime-relative-path>
                <binary-origin>../../Simple Marauroa Java/Card Game interface/dist/y.jar</binary-origin>
            </class-path-extension>
        </data>
    </configuration>
</project>

И это выражение пути, которое яИспользую:

/project/configuration/data/class-path-extension[1]/runtime-relative-path/text()

Вот соответствующие части задачи, которую я пытаюсь выполнить:

<target name="s" depends="-define-xmltasks">
        <propertyselector property="subprojects" match="original.project.dir(.*)" select="\1"/>
        <for list="${subprojects}" param="subproject">
            <sequential>
                <xmltask source="nbproject/project.xml" dest="nbproject/project.xml" failWithoutMatch="true">
                    <replace path="/project/configuration/data/class-path-extension[@{subproject}]/runtime-relative-path/text()" 
                             withText="ext/extension/${extension-lib@{subproject}.dist.jar}"/>
                    <replace path="/project/configuration/data/class-path-extension[@{subproject}]/binary-origin/text()" 
                             withText="${original.project.dir@{subproject}}/dist/${extension-lib@{subproject}.dist.jar}"/>
                </xmltask>
            </sequential>
        </for>
    </target>

@ {subproject} преобразуется в число и уже пытался изменить егодля числа, но имеет тот же эффект.Есть идеи?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2012

И это выражение пути, которое я использую:

/project/configuration/data/class-path-extension[1]/runtime-relative-path/text()

Один из способов справиться с нефиксированными именами, которые находятся в непустом (по умолчанию) пространстве имен, - это указать имя в качестве предиката.

Вот выражение XPath, написанное в этом стиле, которое выбирает нужные узлы:

   /*[name()='project']
     /*[name()='configuration']
       /*[name()='data']
         /*[name()='class-path-extension'][1]
           /*[name()='runtime-relative-path']
             /text()

Проверка на основе XSLT:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*[name()='project']
     /*[name()='configuration']
       /*[name()='data']
         /*[name()='class-path-extension'][1]
           /*[name()='runtime-relative-path']
             /text()
  "/>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному документу XML :

<project xmlns="http://www.netbeans.org/ns/project/1">
    <type>org.netbeans.modules.apisupport.project</type>
    <configuration>
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
            <code-name-base>simple.server.extension.cardgame</code-name-base>
            <suite-component/>
            <module-dependencies>
                <dependency>
                    <code-name-base>marauroa.lib</code-name-base>
                    <build-prerequisite/>
                    <compile-dependency/>
                    <run-dependency>
                        <release-version>3</release-version>
                        <specification-version>8</specification-version>
                    </run-dependency>
                </dependency>
                <dependency>
                    <code-name-base>simple.server.lib</code-name-base>
                    <build-prerequisite/>
                    <compile-dependency/>
                    <run-dependency>
                        <release-version>0-1</release-version>
                        <specification-version>0.2</specification-version>
                    </run-dependency>
                </dependency>
            </module-dependencies>
            <public-packages>
                <package>dreamer.card.game</package>
                <package>dreamer.card.game.model.events</package>
                <package>dreamer.card.game.price</package>
                <package>dreamer.card.game.storage</package>
                <package>simple.server.extension</package>
                <package>simple.server.extension.card</package>
            </public-packages>
            <class-path-extension>
                <runtime-relative-path>ext/extension/x.jar</runtime-relative-path>
                <binary-origin>../../Simple Marauroa Java/Card Game Extension/dist/x.jar</binary-origin>
            </class-path-extension>
            <class-path-extension>
                <runtime-relative-path>ext/extension/y.jar</runtime-relative-path>
                <binary-origin>../../Simple Marauroa Java/Card Game interface/dist/y.jar</binary-origin>
            </class-path-extension>
        </data>
    </configuration>
</project>

вычисляется выражение XPath и выбранный узел копируется в вывод :

ext/extension/x.jar

Примечание : Для создания и проверки выражений XPath можно использовать такой инструмент, как визуализатор XPath . Этот инструмент помог многим тысячам людей освоить XPath в увлекательной игровой форме.

2 голосов
/ 21 февраля 2012

Проблема в том, что элементы project и data объявлены в разных пространствах имен.Вы можете использовать атрибут local-name() в предикате узла следующим образом:

/*[local-name() = 'project'] ...

Вы также можете указать пространство имен, используя атрибут namespace-uri:

/*[local-name() = 'project' and namespace-uri() = 'http://www.netbeans.org/ns/project/1'] ...

и т. Д.

...