XSLT-1.0:更改属性的值

时间:2016-10-14 20:46:44

标签: xml xslt xslt-1.0

我有以下输入xml文件:

Executing tasks: [:app:generateReleaseSources, :app:prepareReleaseUnitTestDependencies, :app:mockableAndroidJar]

Configuration on demand is an incubating feature.
:app:preBuild UP-TO-DATE
:app:preReleaseBuild UP-TO-DATE
:app:checkReleaseManifest 
:app:preDebugBuild UP-TO-DATE 
:app:prepareComAndroidDatabindingAdapters121Library UP-TO-DATE 
:app:prepareComAndroidDatabindingLibrary121Library UP-TO-DATE 
:app:prepareComAndroidSupportAnimatedVectorDrawable2421Library UP-TO-DATE 
:app:prepareComAndroidSupportAppcompatV72421Library UP-TO-DATE 
:app:prepareComAndroidSupportCardviewV72421Library UP-TO-DATE 
:app:prepareComAndroidSupportDesign2421Library UP-TO-DATE 
:app:prepareComAndroidSupportRecyclerviewV72421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportCompat2421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportCoreUi2421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportCoreUtils2421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportFragment2421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportMediaCompat2421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportV42421Library UP-TO-DATE 
:app:prepareComAndroidSupportSupportVectorDrawable2421Library UP-TO-DATE 
:app:prepareReleaseDependencies :app:compileReleaseAidl UP-TO-DATE 
:app:compileReleaseRenderscript UP-TO-DATE 
:app:generateReleaseBuildConfig UP-TO-DATE 
:app:generateReleaseResValues UP-TO-DATE 
:app:generateReleaseResources UP-TO-DATE 
:app:mergeReleaseResources 
:app:dataBindingProcessLayoutsRelease 
:app:processReleaseManifest 
:app:processReleaseResources 
AGPBI: {"kind":"error","text":"Error parsing XML: duplicate attribute","sources":[{"file":"D:\\Android\\Android Projects\\UTClinicalNursing\\app\\build\\intermediates\\data-binding-layout-out\\release\\layout\\activity_sign_up.xml","position":{"startLine":22}}],"original":"","tool":"AAPT"}
D:\Android\Android Projects\UTClinicalNursing\app\build\intermediates\data-binding-layout-out\release\layout\activity_sign_up.xml:23: error: Error parsing XML: duplicate attribute



FAILED

FAILURE: Build failed with an exception.

* What went wrong: Execution failed for task ':app:processReleaseResources'.
> com.android.ide.common.process.ProcessException: Failed to execute aapt

* Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

如果$ cat data.xml <?xml version="1.0" encoding="UTF-8" standalone="no"?> <root> <outer id="0" status="FAIL" > <nested status="FAIL" > <inner status="FAIL" > <innermost status="FAIL" /> </inner> </nested> </outer> <outer id="1" status="VOID"> <nested status="VOID" > <inner status="VOID" > <innermost status="VOID" /> <innermost status="VOID" /> </inner> </nested> </outer> </root> status,则此xsl文件应将VOID属性的值更改为FAIL

$ cat filter.xsl 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" omit-xml-declaration="no"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[@status = 'FAIL']">
  <!--xsl:template match="*/@status[. = 'FAIL']"-->
    <xsl:copy>
      <xsl:attribute name="status">VOID</xsl:attribute>
      <!--xsl:attribute name="newattribute">NEW VALUE</xsl:attribute-->
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

然而,它并没有改变任何东西。我知道我匹配正确的节点,因为我可以在应该发生更改的步骤中添加新属性:

...
<!-- This works fine -->
<xsl:attribute name="newattribute">NEW VALUE</xsl:attribute>
...

如何更改status的价值?

1 个答案:

答案 0 :(得分:3)

  

然而,它并没有改变任何东西。

实际上,那不是真的。你的代码工作正常,这个:

<xsl:attribute name="status">VOID</xsl:attribute>

会创建一个名为status的新属性,其值为"VOID"

问题在于接下来会发生什么。这条指令:

<xsl:apply-templates select="@*|node()"/>

复制上下文元素的现有属性 - 由于其中一个属性也被命名为status,它会覆盖您刚刚创建的status属性。

您可以通过更改顺序来解决此问题:

<xsl:template match="*[@status = 'FAIL']">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:attribute name="status">VOID</xsl:attribute>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

但更简单的解决方案是关注属性:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="@status[. = 'FAIL']">
    <xsl:attribute name="status">VOID</xsl:attribute>
</xsl:template>

</xsl:stylesheet>