Очистка значения узла от и файла XML с помощью XSLT - PullRequest
3 голосов
/ 28 февраля 2012

У меня есть следующий XML-документ

    <?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22" solutionVersion="1.0.0.65" productVersion="14.0.0.0" PIVersion="1.0.0.0" href="https://devcoop.oceanspray.com/sites/TCM2/FormServerTemplates/TCM-TCP.xsn"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.3"?>
<my:myFields xml:lang="en-US" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
  <my:Header>
    <my:ProjectName>Something</my:ProjectName>
    <my:ProjectCreationDate>2/21/2012 12:00 AM</my:ProjectCreationDate>
  </my:Header>
  <my:Details>
    <my:DescriptionOfProposal>
      Will be filled in when saved<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"><p>testestdsgsgasfgf a<strong>asdf </strong>adf asdf asdf as</p></html>
    </my:DescriptionOfProposal>
    <my:PurposeOfChange>Will be filled in when saved</my:PurposeOfChange>
  </my:Details>
</my:myFields>

Я хочу запустить файл XSLT над этим документом, который очистит значение узла my: DescriptionOfPropsal. Это полностью очистит текст и дочерние узлы. У меня есть следующая таблица стилей XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="//my:DescriptionOfProposal">
    <my:DescriptionOfProposal>
    </my:DescriptionOfProposal>
  </xsl:template>


</xsl:stylesheet>

Но, похоже, это не работает. Я провел с ним кучу тестов и считаю, что это как-то связано с пространством имен на узле, потому что я могу выполнить тот же тип преобразования для другого простого документа без пространств имен, и я смогу заставить его работать.

Ответы [ 3 ]

1 голос
/ 28 февраля 2012

Это очевидно - вы используете неправильное пространство имен .

Узел my:DescriptionOfProposal в предоставленном XML-документе принадлежит пространству имен:

"http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22"

Однако в своем коде XSLT вы связываете префикс "my:" с другим пространством имен:

"urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22"

Решение

Исправьте пространство имен в своем преобразовании.

Заменить

xmlns:my="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22"

с

xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22"

С этим изменением и небольшим рефакторингом переопределяющего шаблона ваше преобразование становится:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="my:DescriptionOfProposal/node()"/>
</xsl:stylesheet>

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

<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22" solutionVersion="1.0.0.65" productVersion="14.0.0.0" PIVersion="1.0.0.0" href="https://devcoop.oceanspray.com/sites/TCM2/FormServerTemplates/TCM-TCP.xsn"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.3"?>
<my:myFields xml:lang="en-US" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
    <my:Header>
        <my:ProjectName>Something</my:ProjectName>
        <my:ProjectCreationDate>2/21/2012 12:00 AM</my:ProjectCreationDate>
    </my:Header>
    <my:Details>
        <my:DescriptionOfProposal>       Will be filled in when saved
            <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml">
                <p>testestdsgsgasfgf a
                    <strong>asdf </strong>adf asdf asdf as
                </p>
            </html>
        </my:DescriptionOfProposal>
        <my:PurposeOfChange>Will be filled in when saved</my:PurposeOfChange>
    </my:Details>
</my:myFields>

желаемый, правильный результат выдается :

<?xml version="1.0" encoding="UTF-16"?>
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22" solutionVersion="1.0.0.65" productVersion="14.0.0.0" PIVersion="1.0.0.0" href="https://devcoop.oceanspray.com/sites/TCM2/FormServerTemplates/TCM-TCP.xsn"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.3"?>
<my:myFields xml:lang="en-US" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
    <my:Header>
        <my:ProjectName>Something</my:ProjectName>
        <my:ProjectCreationDate>2/21/2012 12:00 AM</my:ProjectCreationDate>
    </my:Header>
    <my:Details>
        <my:DescriptionOfProposal></my:DescriptionOfProposal>
        <my:PurposeOfChange>Will be filled in when saved</my:PurposeOfChange>
    </my:Details>
</my:myFields>
1 голос
/ 28 февраля 2012

Так как все остальные диагностировали проблему с пространством имен и нашли решение, пожалуйста, обратитесь к ответам, чтобы исправить ваш код. Однако я бы хотел предложить вам что-то еще, кроме исправления пространства имен . Его использование contains() function .. Я знаю, что в данном случае это бесполезно, но просто для того, чтобы делиться знаниями, я пишу это решение:)

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node()[contains(name(),'DescriptionOfProposal')]">
    <xsl:copy/>
  </xsl:template>
</xsl:stylesheet>

Приведенный выше код никогда не заботился о том, какое пространство имен вы используете в XML-файле:)

Это альтернатива этому ..

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node()[parent:: node()[contains(name(),'DescriptionOfProposal')]]"/>
</xsl:stylesheet>

Вы можете использовать любой из них :) РЕДАКТИРОВАТЬ: второй метод наименее предпочтителен из-за обратных осей :)
Этот метод добавлен по предложению Димитра ...

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node()[local-name() = 'DescriptionOfProposal']">
    <xsl:copy/>
  </xsl:template>
</xsl:stylesheet>
0 голосов
/ 28 февраля 2012

Пространство имен, к которому вы привязаны my, отличается в XML и XSLT:

XML:

xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22"

XSLT:

xmlns:my="urn:schemas-microsoft-com:office:infopath:TCM-TCP:-myXSD-2012-02-20T14-33-22"

Либо измените пространство имен в вашем XSLT, либо добавьте новое. E.g.:

xmlns:my2="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-20T14:33:22"

А потом в вашем шаблоне:

<xsl:template match="my2:DescriptionOfProposal">
    <my2:DescriptionOfProposal/>
</xsl:template>

Обратите внимание, что // совершенно не нужен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...