选择并修改节点,使用xlst保持其余部分不变

时间:2018-05-21 12:45:03

标签: xslt xslt-1.0

我有以下XML:

<?xml version="1.0" encoding="utf-8" ?>
<DOCUMENT>
    <SECTION>
        <PARAGRAPH TRACK="4">
            <SENTENCE NAME="PRIMARY" COUNT="4">
                <TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
                <TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
                <TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" />
                <TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" />
            </SENTENCE>
            <SENTENCE NAME="SECONDARY" COUNT="2">
                <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
                <TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" />
            </SENTENCE>
            <SENTENCE NAME="SECONDARY" COUNT="1">
                <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />                    
            </SENTENCE>
        </PARAGRAPH>
    </SECTION>
</DOCUMENT>

我需要获得以下结果,TOKEN语句选择节点IF,并使用属性NEW进行更新:

<?xml version="1.0" encoding="utf-8" ?>
<DOCUMENT>
    <SECTION>
        <PARAGRAPH TRACK="4">
            <SENTENCE NAME="PRIMARY" COUNT="4">
                <TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
                <TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
                <TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" />
                <TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" />
            </SENTENCE>
            <SENTENCE NAME="SECONDARY" COUNT="2">
                <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
                <TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" />
            </SENTENCE>
            <SENTENCE NAME="SECONDARY" COUNT="1">
                <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" NEW="YES" />
                <TOKEN></TOKEN>
            </SENTENCE>
        </PARAGRAPH>
    </SECTION>
</DOCUMENT>

使用以下XSLT转换,我获得了错误的结果,其中IF语句选择的节点TOKEN被复制到树的开头:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
 <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
 </xsl:template>
  <xsl:key name="primary_tokens" 
    match="SENTENCE[@NAME='PRIMARY']/TOKEN" 
    use="concat(@SENTENCE_BEGIN,'|',@SENTENCE_END)"/>
  <xsl:template match="/*">
    <xsl:for-each select=".//TOKEN[@DOUBLE='YES'][key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))]">
      <xsl:if test="key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))[@BEGIN > current()/@BEGIN]">
        <xsl:copy>
            <xsl:attribute name="NEW">YES</xsl:attribute>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy> 
      </xsl:if>
    </xsl:for-each>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

不需要的结果:

<?xml version="1.0" encoding="utf-16"?>
<TOKEN NEW="YES" BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
<DOCUMENT>
  <SECTION>
    <PARAGRAPH TRACK="4">
      <SENTENCE NAME="PRIMARY" COUNT="4">
        <TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
        <TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
        <TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" />
        <TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" />
      </SENTENCE>
      <SENTENCE NAME="SECONDARY" COUNT="2">
        <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
        <TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" />
      </SENTENCE>
      <SENTENCE NAME="SECONDARY" COUNT="1">
        <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
      </SENTENCE>
    </PARAGRAPH>
  </SECTION>
</DOCUMENT>

我提出了一个可能的解决方案,在xsl:template match="//SECTION/PARAGRAPH/SENTENCE[@NAME='SECONDARY']/TOKEN条件中添加了TOKEN。不幸的是,即使这个解决方案也不正确,因为内容SENTENCE节点只是复制到<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:key name="primary_tokens" match="SENTENCE[@NAME='PRIMARY']/TOKEN" use="concat(@SENTENCE_BEGIN,'|',@SENTENCE_END)"/> <xsl:template match="//SECTION/PARAGRAPH/SENTENCE[@NAME='SECONDARY']/TOKEN"> <xsl:for-each select="current()[key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))]"> <xsl:if test="key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))[@BEGIN > current()/@BEGIN]"> <xsl:attribute name="NEW">YES</xsl:attribute> <xsl:apply-templates select="@*|node()"/> </xsl:if> </xsl:for-each> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> 节点中:

TOKEN

SENTENCE节点中<?xml version="1.0" encoding="utf-16"?> <DOCUMENT> <SECTION> <PARAGRAPH TRACK="4"> <SENTENCE NAME="PRIMARY" COUNT="4"> <TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" /> <TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" /> <TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" /> <TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" /> </SENTENCE> <SENTENCE NAME="SECONDARY" COUNT="2"> <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" /> <TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" /> </SENTENCE> <SENTENCE NAME="SECONDARY" COUNT="1" NEW="YES" BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES"> <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" /> <TOKEN /> </SENTENCE> </PARAGRAPH> </SECTION> </DOCUMENT> 的错误输出:

You are running Composer with SSL/TLS protection disabled.

我的问题是:我如何获得上面报告的通缉结果?我的第二次尝试是否接近一个好的解决方案?

1 个答案:

答案 0 :(得分:1)

我认为你的第二次尝试很接近;你想要匹配TOKEN,如果那是你想要更新的。

试试这个......

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

  <xsl:key name="primary_tokens" 
    match="SENTENCE[@NAME='PRIMARY']/TOKEN" 
    use="concat(@SENTENCE_BEGIN,'|',@SENTENCE_END)"/>

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

  <xsl:template match="TOKEN[@DOUBLE='YES']">
    <xsl:copy>
      <xsl:if test="key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))[@BEGIN > current()/@BEGIN]">
        <xsl:attribute name="NEW">YES</xsl:attribute>
      </xsl:if>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

小提琴:http://xsltfiddle.liberty-development.net/bdxtpX