Пространство имен XML выбрасывает мой XSLT - PullRequest
1 голос
/ 15 июля 2011

У меня есть XML-документ с пространством имен, которое выглядит примерно так: я просто упростил его, чтобы задать вопрос.

<MyNameSpace xmlns="http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace">
<IDmain>ins</IDmain>
    <Table_1 class="entity">
        <Address>Oak Park Drive</BillingProviderAddress>
        <City>Lake Elizabeth</BillingProviderCity>
        <Name>Corporation</BillingProviderOrgName>
        <InvoiceLine class ="entity">
            <DateService>1234</DateService>
        </InvoiceLine>
    <Table_1>
</MyNameSpace>

Затем я создал XSLT здесь. Я понимаю, это уродливо, я не эксперт по XSLT, но это был один из тех моментов, которые «просто решили проблему».

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">

<xsl:variable name="vPrefix">
<xsl:value-of select="MyNameSpace/Table_1/Address"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="MyNameSpace/Table_1/City"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="MyNameSpace/Table_1/Name"/>
<xsl:text>|</xsl:text>
</xsl:variable>

<xsl:for-each select="MyNameSpace/Table_1/InvoiceLine">
        <xsl:value-of select="$vPrefix"/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="DateService"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Теперь XSLT делает именно то, что мне нужно, проблема в том, что мои тестовые данные включают это классное пространство имен в верхней части XML-документа.

XMLNS = "http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace"

Две вещи, я использую XMLPAD , и когда я запускаю скрипт, он на самом деле прекрасно работает с пространством имен.

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

Я точно знаю, что пространство имен отбрасывает XSLT, который я использую, потому что, когда я удаляю его из XML, он отлично работает в тестировании. Однако это решение не является правдоподобным, поскольку весь этот процесс фактически автоматизирован. Поэтому мне нужно решение проблемы с пространством имен.

Anythoughts

Ответы [ 2 ]

5 голосов
/ 15 июля 2011

XPath , который является частью XSLT, который вы используете для соответствия определенным элементам, чувствителен к пространству имен.Если у вас XPath, такой как MyNameSpace/Table_1/Address, вы сопоставляете элементы без какого-либо пространства имен XML ;а именно, любой элемент Address, который является дочерним по отношению к любому элементу Table_1, который является дочерним по отношению к любому элементу MyNameSpace, который является дочерним по отношению к текущему контекстному узлу.

Вам необходимо добавить префиксы пространства имен;Например:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:z="http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace">

...

<xsl:value-of select="z:MyNameSpace/z:Table_1/z:Address"/>

К сожалению, XSLT 1.0 не учитывает текущее пространство имен по умолчанию при оценке XPath, поэтому вы не можете просто установить пространство имен по умолчанию и покончить с этим;вам действительно нужен префикс пространства имен.

Если вы можете использовать XSLT 2.0, вы можете использовать атрибут xpath-default-namespace, чтобы установить пространство имен по умолчанию для элементов, на которые ссылаются запросы XPath.(XSLT 2.0 немного более практичен во многих небольших аспектах, как это ...)

2 голосов
/ 15 июля 2011

Вы можете использовать общее соответствие для элементов и фильтр предикатов на local-name()

например. *[local-name()='MyNameSpace']/*[local-name()='Table_1']/*[local-name()='Address']

ПРЕДУПРЕЖДЕНИЕ: Это более общее совпадение, поэтому вы можете получить непредсказуемые результаты, если у вас есть документ с другими элементами, определенными в пространстве имен с тем же именем.

...