2016-07-05 2 views
0

Я пытаюсь запустить deep-equal function, чтобы сравнить 2 последовательности узлов. Для последовательностей, которые, как я ожидаю, будут согласованы, единственная разница будет заключаться в том, что некоторые каретки возвращаются здесь и там и дополнительный элемент ID для одной из последовательностей.xslt - Использование глубокого равенства по нормализованному тексту

Так, например:

<body> 
<section> 
    <p>that's a paragraph</p> 
    <p @class="p1">that's another paragraph</p> 
</section> 
</body> 

и:

<body> 
<section id="1"> 
    <p id="2">that's a 
paragraph</p> 
    <p @class="p1" id="3">that's another paragraph</p> 
</section> 
</body> 

Для меня, это совпадение.

Теперь deep-equal не нравится возврат каретки и идентификатор. Поэтому я пытался изменить его, чтобы убедиться, что он все еще соответствует.

Использование remove-attributes-deep, я завернут глубоко равен:

<xsl:function name="functx:deep-similar" as="xs:boolean"> 
    <xsl:param name="seq1" as="item()*"/> 
    <xsl:param name="seq2" as="item()*"/> 

    <xsl:variable name="seq1-noId" select="functx:remove-attributes-deep($seq1,'id')"/> 
    <xsl:variable name="seq2-noId" select="functx:remove-attributes-deep($seq2,'id')"/> 

    <xsl:sequence select="every $i in 1 to max((count($seq1-noId), count($seq2-noId))) 
    satisfies deep-equal($seq1-noId[$i], $seq2-noId[$i])"/>  
</xsl:function> 

Этот код в основном код из sequence-deep-equal с remove-attributes-deep поверх него.

Теперь я хотел бы настроить его, чтобы нормализовать пространства.

Как я могу нормализовать отдельный текст() каждого узла последовательности, сохраняя узлы, чтобы я мог работать с ними на одном уровне после обновления? Мне нужно, чтобы он находился внутри самой функции.

Я не могу скрыть свои файлы, некоторые пространства имеют решающее значение для меня.

+0

Вы должны взглянуть на функцию [normalize-space] (http://www.xsltfunctions.com/xsl/fn_normalize-space.html) – potame

+0

yes, но она возвращает только строку. Как я могу перестроить узел с нормализованным текстом? – Flag

+0

Почему у вас есть требование «Мне нужно, чтобы он находился внутри самой функции»? Я бы предложил написать некоторые шаблоны с определенным режимом, который разделяет атрибуты, которые вы хотите разбить и нормализовать текстовые узлы по своему усмотрению (или, возможно, присвоить значения), а затем вы можете использовать шаблоны приложений в своих входных последовательностях в этом режиме и сравните результат. –

ответ

1

Я хотел бы предложить, чтобы определить именованный режим, который выполняет преобразование (то есть значение текста нормализация и id удаления атрибутов) необходимо выполнить перед сравнением с deep-equal:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:variable name="t1"> 
     <body> 
      <section> 
       <p>that's a paragraph</p> 
       <p class="p1">that's another paragraph</p> 
      </section> 
     </body>  
    </xsl:variable> 

    <xsl:variable name="t2"> 
     <body> 
      <section id="1"> 
       <p id="2">that's a 
        paragraph</p> 
       <p class="p1" id="3">that's another paragraph</p> 
      </section> 
     </body> 
    </xsl:variable> 

    <xsl:template name="main"> 
     <xsl:variable name="nt1"> 
      <xsl:apply-templates select="$t1" mode="normalize"/> 
     </xsl:variable> 
     <xsl:variable name="nt2"> 
      <xsl:apply-templates select="$t2" mode="normalize"/> 
     </xsl:variable> 

     <xsl:value-of select="'deep-equal($t1, $t2): ', deep-equal($t1, $t2), '; deep-equal($nt1, $nt2): ', deep-equal($nt1, $nt2)"/> 
    </xsl:template> 

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

    <xsl:template match="text()" mode="normalize"> 
     <xsl:value-of select="normalize-space()"/> 
    </xsl:template> 

    <xsl:template match="@id" mode="normalize"/> 

</xsl:stylesheet> 

Если вы не хотите, личности преобразования для всех режимов вы можете, конечно, только определить его для указанного режима, то есть заменить

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

по

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

Я все еще неправильно мыслил в XSLT ... Большое спасибо (снова и снова), что бы я сделал без вас: D? Учимся много! – Flag