2014-12-19 2 views
0

Я хотел бы начать с того, что я не очень хорошо разбираюсь в XPATH, и это главная причина, по которой я прихожу к вам, ребята, за помощью.Выведите две отдельные группы узлов на основе общего свойства/значения

Итак, сегодня я работал над попыткой «группировать», или, так сказать, некоторые данные из XML-файла, основываясь на том, что они оба используют идентификатор. Мне удалось, с помощью друга, сделать это, но он был довольно длинным, и я уверен, что должен быть более легкий/чистый способ. Ниже приведен XML-, XSLT-я и желаемый выход:

<Dude> 
    <ID>768</ID> 
    <Name>Mr Dude Man</Name> 
</Dude> 
... 
<Basket> 
     <CustomerID>768</CustomerID> 
     <Purchases> 
      <PurchasedItem> 
       <ItemID>736383-2</ItemID> 
       <ItemName>XSLT Training</ItemName> 
       <ItemType>Book</ItemType> 
       <ItemQuantity>2</ItemQuantity> 
      </PurchasedItem> 
      <PurchasedItem> 
       <ItemID>736383-2</ItemID> 
       <ItemName>Candy</ItemName> 
       <ItemType>Consumable</ItemType> 
       <ItemQuantity>1</ItemQuantity> 
      </PurchasedItem> 
     </Purchases> 
</Basket> 

XSLT-я:

<xsl:apply-templates select="Dude"/> 

<xsl:template match="Dude"> 
    {Name} has purchased: 
    <xsl:apply-templates select="Basket[Basket/CustomerID = ../Dude/ID]"/> 
</xsl:template> 

<xsl:template match="Basket"> 
    {ItemName} 
</xsl:template> 

В приведенном выше примере, каждый Dude может иметь одну корзину и корзина имеет customerID соединенные ему идентифицировать владельца корзины. Предположим, что оба узла настолько глубоки, как друг друга. Как бы я пошел, используя xpath на <apply-templates/>, чтобы получить следующий результат:

ps. Не беспокойтесь, чтобы много о фактическом выходе, я просто хочу знать правильный способ перемещения в XML-дерево, подбирая на одном из узлов с помощью apply-templates

Mr Dude Man has purchased: XSLT Training, Candy 

EDIT: Забыл XSLT Я б ... Теперь я смущен, что это лучший способ сделать это? С двумя отдельными матчами. Также внутри предиката мне нужна ../ или же предикат Предположим, я начинаю в том, где я был подобран, например: Dude

+0

Можете ли вы опубликовать свой ввод xml с контекстом? – Rnet

+0

Не могли бы вы опубликовать более подробный пример? Кажется, что у любого чувака/дудета может быть больше одной корзины - что тогда будет ожидаемым результатом? И каков формат результата: XML, HTML или текст? –

+0

_ "Ниже приведен XML, XSLT, который я использовал" _ Я не вижу XSLT в вашем вопросе. – JLRishe

ответ

2

Эффективный способ сделать перекрестные ссылки, как это использовать ключ:

<xsl:key name='kBasket' match="Basket" use="CustomerID" /> 

Тогда вы можете сделать это:

<xsl:template match="/"> 
    <xsl:apply-templates select="/Full/Path/To/Dude" /> 
</xsl:template> 

<xsl:template match="Dude"> 
    {Name} has purchased: 
    <xsl:apply-templates select="key('kBasket', ID)"/> 
</xsl:template> 

<xsl:template match="Basket"> 
    <-- Any per-basket stuff could be output here --> 
    <xsl:apply-templates select="Purchases/PurchasedItem" /> 
</xsl:template> 

<xsl:template match="PurchasedItem"> 
    <xsl:value-of select="ItemName" /> 
</xsl:template> 


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

<xsl:apply-templates select="/Absolute/Path/To/Basket[CustomerID = current()/ID]"/> 

но ключ подход является предпочтительным, поскольку он является более эффективным.

+0

Большое спасибо за это. Это именно то, о чем я просил ... Я просто не очень хорошо задавал вопросы правильно. Молодец и счастливое Рождество! : P – Aleski

+0

@JLRishe, как вы избегаете повторения «корзины» за пределами шаблона «Чувак»? – Rnet

+0

@Rnet Типичным способом было бы иметь шаблоны ранее в процессе, чтобы поток управления направлялся к 'Dude' и не позволял ему спускаться по маршруту, ведущему к' Basket'. Например: ''. Если вы просто разрешите обработку, не контролируя ее, вы можете завершить работу с '' '' '' '' '' '' '' '' обработкой 'обрабатывается дважды. – JLRishe