Вычислите weeknumber от значения даты

Я закончил тем, что использовал MutationObservers в JavaScript, чтобы отслеживать изменения в DOM внутри iFrame, чтобы скрыть меню, которые не должны были видеть не администраторы. Решение написано на AngularJS 1.2 и, как известно, работает с Kibana 6.2 и 6.3. Это скроет несколько «левых» меню, а также несколько подменю управления. Вы можете использовать или изменить код, чтобы скрыть / показать дополнительные элементы пользовательского интерфейса. К сожалению, мне пришлось много полагаться на классы, так как очень немногие элементы содержали идентификаторы, на которые я мог ссылаться.

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

HTML:

    <iframe id="AnalysisFrame" ng-src="{{kibanaUrl}}" ng-init="setupFrame()"></iframe>

JavaScript:

    $scope.setupFrame = function() {
        //iframes are excluded from mutation observation, so we will
        //  need to create an observer _inside_ the iframe content.
        var theFrame = document.querySelector('#AnalysisFrame');
        //once the frame is loaded, that is when we can now attach our
        //  observer to the frame's content.
        theFrame.onload = function() {
            //console.log('[TRACE] iframe is completely loaded');
            var bIsKibanaAdmin = $scope.bIsKibanaAdmin;
            //the above is TRUE|FALSE set by some outside logic
            //  which does not pertain to this exercise.

            //create an observer instance for Management sub-menus
            var observerMan = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    //console.log('[TRACE] ', mutation);
                    //sub-menus of the Management console area
                    var manArea = theFrame.contentDocument.body.querySelector('kbn-management-landing');
                    if ( manArea ) {
                        //Management area is divided up by panels of related subjects
                        var manPanels = manArea.querySelectorAll('div[class*="page-row"]');
                        if ( manPanels ) manPanels.forEach(function(aPanel) {
                            //console.log('[TRACE] panel=', aPanel);
                            //6.2.4 had <div> titles, 6.3.x has <h3> titles, select based on their class only
                            var panelTitle = aPanel.querySelector('.kuiPanelHeader__title');
                            //if a panel has a title (version panel does not have one), see if hide or not.
                            if ( panelTitle ) switch ( panelTitle.innerText ) {
                                case 'Kibana':
                                    //only hide the Advanced Settings item off this panel
                                    var panelItem = aPanel.querySelector('li > a[href*="#/management/kibana/settings"]');
                                    if ( panelItem ) panelItem.parentElement.hidden = !bIsKibanaAdmin;
                                    break;
                                default:
                                    //most management panels are hidden from non-admins
                                    aPanel.hidden = !bIsKibanaAdmin;
                            }//switch
                        });
                    }
                });
            });
            //configuration of the left menu becomes active observer
            var configMan = {
                    attributes: true, //for when Management becomes the Active menu
                    attributeFilter: ['class'],
                    //attributeOldValue: true,
                    childList: false,
                    characterData: false,
                    //characterDataOldValue: false,
                    //subtree: true,
            };
            //the Management menu item does not exist yet, cannot start observing until later.

            //create an observer instance for left menu
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    //console.log('[TRACE] ', mutation);
                    var leftMenus = mutation.target.querySelectorAll('.global-nav-link');
                    //since the menus do not have IDs, we are searching for their outer
                    //  DIV class unique to all left menu items. Their first element child
                    //  will be the <a href> link we can use to filter out ones we
                    //  wish to show or not.
                    if ( leftMenus ) leftMenus.forEach(function(aMenu) {
                        if ( aMenu.firstElementChild ) {
                            switch ( aMenu.firstElementChild.hash ) {
                                case "#/dev_tools":
                                    aMenu.hidden = !bIsKibanaAdmin;
                                    break;
                                case "#/account":
                                    aMenu.hidden = true;
                                    break;
                                case "":
                                    if ( aMenu.innerText=='Logout' ) {
                                        aMenu.hidden = true;
                                    }
                                    //else console.log('[TRACE] menu=', aMenu);
                                    break;
                                case "#/management":
                                    //we only want to hide certain sub-menus
                                    //  our menu item exists, attach observer for when
                                    //  user clicks it to make it "active"
                                    observerMan.observe(aMenu, configMan);
                                    break;
                                default:
                                    //console.log('[TRACE] menu=', aMenu);
                            }//switch
                        }
                    });
                });
            });
            //configuration of the left menu creation observer
            var configLM = {
                    attributes: false,
                    //attributeFilter: ['src'],
                    //attributeOldValue: true,
                    childList: true,
                    characterData: false,
                    //characterDataOldValue: false,
                    //subtree: true,
            };
            //start observing the contents of the iframe changes
            observer.observe(theFrame.contentDocument.body, configLM);
        };
    };
6
задан Mathias Müller 21 March 2014 в 16:12
поделиться

6 ответов

Если можно использовать EXSLT, существует несколько доступных функций даты. Все они реализованы в саксе, но если Вы используете MSXSL, Chris Bayes реализовал их, поскольку расширение функционирует, который можно на самом деле поместить в преобразовании в msxsl:script элементе. Его реализации связаны от каждой определенной страницы функции даты.

Является неделя в годе () функцией, которую Вы ищете?

Править: На комментарий JeniT существует чистый шаблон XSLT 1.0, доступный на том же сайте с той же функциональностью как неделя в годе () (который она записала, я думаю), который мог бы соответствовать Вашим требованиям лучше.

5
ответ дан 17 December 2019 в 20:36
поделиться

Проверьте Поваренную книгу XSLT Sal Mangano. Интересно достаточно это доступно на Google Books.

Путь xslt 2.0:

<xsl:function name="chkbk:calculate-week-number" as="xs:integer">
    <xsl:param name="date" as="xs:date" />
    <xsl:sequence select="xs:integer(format-date($date,'[W]'))" />
</xsl:function>

Для 1,0 путей посмотрите cookbox предварительный просмотр. BTW, я просто погуглил xslt weeknumber для определения местоположения этого.

0
ответ дан 17 December 2019 в 20:36
поделиться

Недельное вычисление может стать довольно сложным, если Вы всегда хотите, чтобы неделя запустилась в тот же день, потому что первый день года всегда изменяется. Существует стандарт ISO для вычисления его, см. эту статью Wikipedia.

1
ответ дан 17 December 2019 в 20:36
поделиться

Это - чистое решение XSLT 1.0:

Можно использовать datetime_lib.xsl модуль таблицы стилей Martin Rowlinson, который идет с XSelerator (хороший IDE XSLT, недавно сделанный в свободном доступе на SourceForge). Необходимо будет загрузить и установить это приложение, затем Вы найдете богатство дополнительных библиотек и образцы усовершенствованных методов и решений.

datetime_lib.xsl файл может быть найден (для типовой установки) на:

       C:\Program Files\Marrowsoft\Xselerator25\Samples\Libraries\

Из этой библиотеки вот шаблон, названный "недельным числом":

<xsl:template name="week-number">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>
    <!-- or -->
    <xsl:param name="date" select="''"/>  <!-- format: yyyymmdd or yyyy-mm-dd -->
    <!-- or -->
    <xsl:param name="julian-day" select="''"/>
    <!-- trim down date -->
    <xsl:variable name="tdate" select="translate($date,'-','')"/>
    <!-- decide which params were passed -->
    <xsl:variable name="yyyy">
        <xsl:choose>
            <xsl:when test="string-length($date) > 0"><xsl:value-of select="substring($tdate,1,4)"/></xsl:when>
            <xsl:when test="string-length($julian-day) > 0">
                <xsl:variable name="jdate">
                    <xsl:call-template name="julian-day-to-date">
                        <xsl:with-param name="julian-day" select="$julian-day"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="substring($jdate,1,4)"/>
            </xsl:when>
            <xsl:otherwise><xsl:value-of select="$year"/></xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- get the julian day number -->
    <xsl:variable name="jd">
        <xsl:choose>
            <xsl:when test="string-length($julian-day) > 0"><xsl:value-of select="$julian-day"/></xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="date-to-julian-day">
                    <xsl:with-param name="year" select="$year"/>
                    <xsl:with-param name="month" select="$month"/>
                    <xsl:with-param name="day" select="$day"/>
                    <xsl:with-param name="date" select="$date"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- get the julian day number for the first working day of next year -->
    <xsl:variable name="fyjd">
        <xsl:call-template name="first-day-of-year">
            <xsl:with-param name="year" select="$yyyy+1"/>
            <xsl:with-param name="as-julian-day" select="true()"/>
        </xsl:call-template>
    </xsl:variable>
    <!-- decide which the 'working' year for this date is -->
    <xsl:variable name="start-jd">
        <xsl:choose>
            <xsl:when test="$jd >= $fyjd"><xsl:value-of select="$fyjd"/></xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="date-to-julian-day">
                    <xsl:with-param name="date">
                        <xsl:call-template name="first-day-of-year">
                            <xsl:with-param name="year" select="$yyyy"/>
                        </xsl:call-template>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <!-- final calc output -->
    <xsl:value-of select="floor(($jd - $start-jd) div 7) + 1"/>
</xsl:template>



Вот простое преобразование XSLT с помощью шаблона "недельного числа":


<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt">

 <xsl:import href=
 "C:\Program Files\Marrowsoft\Xselerator25\Samples\Libraries\datetime_lib.xsl"/>

 <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:call-template name="week-number">
       <xsl:with-param name="date" select="'2008-11-16'"/>
     </xsl:call-template>
 </xsl:template>
</xsl:stylesheet>

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

   46

Надеюсь, что на этот раз ответ был действительно более полезным.

Удачи,

Dimitre Novatchev.

1
ответ дан 17 December 2019 в 20:36
поделиться

Я программирую в Visual Basic, таким образом, я знаю, как сделать это с помощью VB.NET. Считайте свою дату XML в переменную (давайте назовем ее SomeDate). Затем Вы создаете новую дату, которую Вы знаете, начало года, который содержит Вашу неизвестную дату. Затем Вы позволяете DateDiff функционировать, делают его работу, чтобы сказать Вам недельное число.

Dim SomeDate As Date = ReadDateFromXML()
Dim YearStart As New Date(Year(SomeDate), 1, 1)
Dim WeekNumber As Integer = DateDiff(DateInterval.WeekOfYear, YearStart, SomeDate)
-2
ответ дан 17 December 2019 в 20:36
поделиться

И в C#:

DateTime date = DateTime.Now;
int week = date.DayOfYear / 7;
Console.WriteLine(week);
-3
ответ дан 17 December 2019 в 20:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: